diff --git a/apps/virtual/BUILD b/apps/virtual/BUILD
new file mode 100644
index 0000000..1f3cb57
--- /dev/null
+++ b/apps/virtual/BUILD
@@ -0,0 +1,13 @@
+BUNDLES = [
+    "//apps/virtual/api:onos-apps-virtual-api",
+    "//apps/virtual/app:onos-apps-virtual-app",
+]
+
+onos_app(
+    app_name = "org.onosproject.virtual",
+    category = "Traffic Engineering",
+    description = "Virtual Network Subsystem extension",
+    included_bundles = BUNDLES,
+    title = "Virtual Network Subsystem",
+    url = "http://onosproject.org",
+)
diff --git a/apps/virtual/api/BUILD b/apps/virtual/api/BUILD
new file mode 100644
index 0000000..da7ca40
--- /dev/null
+++ b/apps/virtual/api/BUILD
@@ -0,0 +1,11 @@
+COMPILE_DEPS = CORE_DEPS + JACKSON + [
+    "//apps/tunnel/api:onos-apps-tunnel-api",
+]
+
+TEST_DEPS = TEST_ADAPTERS
+
+osgi_jar_with_tests(
+    test_deps = TEST_DEPS,
+    visibility = ["//visibility:public"],
+    deps = COMPILE_DEPS,
+)
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/AbstractVnetService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/AbstractVnetService.java
new file mode 100644
index 0000000..b3e1d18
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/AbstractVnetService.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+import org.onlab.osgi.ServiceDirectory;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Basis for virtual network service.
+ */
+public abstract class AbstractVnetService
+        implements VnetService {
+
+    private static final String NETWORK_NULL = "Network ID cannot be null";
+
+    protected NetworkId networkId;
+    protected VirtualNetworkService manager;
+    protected ServiceDirectory serviceDirectory;
+
+    public AbstractVnetService(VirtualNetworkService manager,
+                               NetworkId networkId) {
+        checkNotNull(networkId, NETWORK_NULL);
+        this.manager = manager;
+        this.networkId = networkId;
+        this.serviceDirectory = manager.getServiceDirectory();
+    }
+
+    @Override
+    public NetworkId networkId() {
+        return this.networkId;
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/Comparators.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/Comparators.java
new file mode 100644
index 0000000..8c67e00
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/Comparators.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2018-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;
+
+import java.util.Comparator;
+
+/**
+ * Various comparators.
+ */
+public final class Comparators {
+
+    // Ban construction
+    private Comparators() {
+    }
+
+    public static final Comparator<VirtualNetwork> VIRTUAL_NETWORK_COMPARATOR =
+            (v1, v2) -> {
+                int compareId = v1.tenantId().toString().compareTo(v2.tenantId().toString());
+                return (compareId != 0) ? compareId : Long.signum(v1.id().id() - v2.id().id());
+            };
+
+    public static final Comparator<VirtualDevice> VIRTUAL_DEVICE_COMPARATOR =
+            (v1, v2) -> v1.id().toString().compareTo(v2.id().toString());
+
+    public static final Comparator<VirtualPort> VIRTUAL_PORT_COMPARATOR =
+            (v1, v2) -> v1.number().toString().compareTo(v2.number().toString());
+
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualDevice.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualDevice.java
new file mode 100644
index 0000000..98e3e1e
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualDevice.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import org.onlab.packet.ChassisId;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.*;
+
+/**
+ * Default representation of a virtual device.
+ */
+public final class DefaultVirtualDevice extends DefaultDevice implements VirtualDevice {
+
+    private static final String VIRTUAL = "virtual";
+    private static final ProviderId PID = new ProviderId(VIRTUAL, VIRTUAL);
+
+    private final NetworkId networkId;
+
+    /**
+     * Creates a network element attributed to the specified provider.
+     *
+     * @param networkId network identifier
+     * @param id        device identifier
+     */
+    public DefaultVirtualDevice(NetworkId networkId, DeviceId id) {
+        super(PID, id, Type.VIRTUAL, VIRTUAL, VIRTUAL, VIRTUAL, VIRTUAL,
+              new ChassisId(0));
+        this.networkId = networkId;
+    }
+
+    @Override
+    public NetworkId networkId() {
+        return networkId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(networkId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultVirtualDevice) {
+            DefaultVirtualDevice that = (DefaultVirtualDevice) obj;
+            return super.equals(that) && Objects.equals(this.networkId, that.networkId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("networkId", networkId).toString();
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualHost.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualHost.java
new file mode 100644
index 0000000..61f31b1
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualHost.java
@@ -0,0 +1,101 @@
+/*
+ * 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;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default representation of a virtual host.
+ */
+public final class DefaultVirtualHost extends DefaultHost implements VirtualHost {
+
+    private static final String VIRTUAL = "virtual";
+    private static final ProviderId PID = new ProviderId(VIRTUAL, VIRTUAL);
+
+    private final NetworkId networkId;
+
+    /**
+     * Creates a virtual host attributed to the specified provider.
+     *
+     * @param networkId network identifier
+     * @param id        host identifier
+     * @param mac       host MAC address
+     * @param vlan      host VLAN identifier
+     * @param location  host location
+     * @param ips       host IP addresses
+     */
+    public DefaultVirtualHost(NetworkId networkId, HostId id, MacAddress mac,
+                              VlanId vlan, HostLocation location, Set<IpAddress> ips) {
+        this(networkId, id, mac, vlan, Collections.singleton(location), ips);
+    }
+
+    /**
+     * Creates a virtual host attributed to the specified provider.
+     *
+     * @param networkId network identifier
+     * @param id        host identifier
+     * @param mac       host MAC address
+     * @param vlan      host VLAN identifier
+     * @param locations host locations
+     * @param ips       host IP addresses
+     */
+    public DefaultVirtualHost(NetworkId networkId, HostId id, MacAddress mac,
+                              VlanId vlan, Set<HostLocation> locations, Set<IpAddress> ips) {
+        super(PID, id, mac, vlan, locations, ips, false, DefaultAnnotations.builder().build());
+        this.networkId = networkId;
+    }
+
+    @Override
+    public NetworkId networkId() {
+        return networkId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(networkId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultVirtualHost) {
+            DefaultVirtualHost that = (DefaultVirtualHost) obj;
+            return super.equals(that) && Objects.equals(this.networkId, that.networkId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("networkId", networkId).toString();
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualLink.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualLink.java
new file mode 100644
index 0000000..20924bc
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualLink.java
@@ -0,0 +1,186 @@
+/*
+ * 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;
+
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Default representation of a virtual link.
+ */
+public final class DefaultVirtualLink extends DefaultLink implements VirtualLink {
+
+    private static final String VIRTUAL = "virtualLink";
+    public static final ProviderId PID = new ProviderId(VIRTUAL, VIRTUAL);
+
+    private final NetworkId networkId;
+    private final TunnelId tunnelId;
+
+    /**
+     * Private constructor for a default virtual link.
+     *
+     * @param networkId network identifier
+     * @param src       source connection point
+     * @param dst       destination connection point
+     * @param state     link state
+     * @param tunnelId  tunnel identifier
+     */
+    private DefaultVirtualLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst,
+                               State state, TunnelId tunnelId) {
+        super(PID, src, dst, Type.VIRTUAL, state, DefaultAnnotations.builder().build());
+        this.networkId = networkId;
+        this.tunnelId = tunnelId;
+    }
+
+    @Override
+    public NetworkId networkId() {
+        return networkId;
+    }
+
+    /**
+     * Returns the tunnel identifier.
+     *
+     * @return tunnel identifier.
+     */
+    public TunnelId tunnelId() {
+        return tunnelId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(networkId, tunnelId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultVirtualLink) {
+            DefaultVirtualLink that = (DefaultVirtualLink) obj;
+            return super.equals(that) &&
+                    Objects.equals(this.networkId, that.networkId) &&
+                    Objects.equals(this.tunnelId, that.tunnelId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("networkId", networkId).add("tunnelId", tunnelId).toString();
+    }
+
+    /**
+     * Creates a new default virtual link builder.
+     *
+     * @return default virtual link builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for DefaultVirtualLink objects.
+     */
+    public static final class Builder extends DefaultLink.Builder {
+        private NetworkId networkId;
+        private ConnectPoint src;
+        private ConnectPoint dst;
+        private TunnelId tunnelId;
+        private State state;
+
+        private Builder() {
+            // Hide constructor
+        }
+
+        /**
+         * Sets the network identifier to be used by the builder.
+         *
+         * @param networkId network identifier
+         * @return self
+         */
+        public Builder networkId(NetworkId networkId) {
+            this.networkId = networkId;
+            return this;
+        }
+
+        /**
+         * Sets the source connect point to be used by the builder.
+         *
+         * @param src source connect point
+         * @return self
+         */
+        public Builder src(ConnectPoint src) {
+            this.src = src;
+            return this;
+        }
+
+        /**
+         * Sets the destination connect point to be used by the builder.
+         *
+         * @param dst new destination connect point
+         * @return self
+         */
+        public Builder dst(ConnectPoint dst) {
+            this.dst = dst;
+            return this;
+        }
+
+        /**
+         * Sets the tunnel identifier to be used by the builder.
+         *
+         * @param tunnelId tunnel identifier
+         * @return self
+         */
+        public Builder tunnelId(TunnelId tunnelId) {
+            this.tunnelId = tunnelId;
+            return this;
+        }
+
+        /**
+         * Sets the link state to be used by the builder.
+         *
+         * @param state link state
+         * @return self
+         */
+        public Builder state(State state) {
+            this.state = state;
+            return this;
+        }
+
+        /**
+         * Builds a default virtual link object from the accumulated parameters.
+         *
+         * @return default virtual link object
+         */
+        public DefaultVirtualLink build() {
+            checkNotNull(src, "Source connect point cannot be null");
+            checkNotNull(dst, "Destination connect point cannot be null");
+            checkNotNull(networkId, "Network Id cannot be null");
+
+            return new DefaultVirtualLink(networkId, src, dst, state, tunnelId);
+        }
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetwork.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetwork.java
new file mode 100644
index 0000000..bf7de57
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetwork.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import org.onosproject.net.TenantId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default implementation of the virtual network descriptor.
+ */
+public final class DefaultVirtualNetwork implements VirtualNetwork {
+
+    private final NetworkId id;
+    private final TenantId tenantId;
+
+    /**
+     * Creates a new virtual network descriptor.
+     *
+     * @param id       network identifier
+     * @param tenantId tenant identifier
+     */
+    public DefaultVirtualNetwork(NetworkId id, TenantId tenantId) {
+        this.id = id;
+        this.tenantId = tenantId;
+    }
+
+    @Override
+    public NetworkId id() {
+        return id;
+    }
+
+    @Override
+    public TenantId tenantId() {
+        return tenantId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, tenantId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultVirtualNetwork) {
+            DefaultVirtualNetwork that = (DefaultVirtualNetwork) obj;
+            return Objects.equals(this.id, that.id)
+                    && Objects.equals(this.tenantId, that.tenantId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("id", id)
+                .add("tenantId", tenantId)
+                .toString();
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualPort.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualPort.java
new file mode 100644
index 0000000..d5f3efb
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualPort.java
@@ -0,0 +1,106 @@
+/*
+ * 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;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.Element;
+import org.onosproject.net.PortNumber;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default representation of a virtual port.
+ */
+public final class DefaultVirtualPort extends DefaultPort implements VirtualPort {
+
+    private final NetworkId networkId;
+    private final ConnectPoint realizedBy;
+
+    /**
+     * Creates a virtual port.
+     *
+     * @param networkId  network identifier
+     * @param device     parent network element
+     * @param portNumber port number
+     * @param realizedBy underling port which realizes this virtual port
+     */
+    public DefaultVirtualPort(NetworkId networkId, Device device, PortNumber portNumber,
+                              ConnectPoint realizedBy) {
+        this(networkId, device, portNumber, false, realizedBy);
+    }
+
+    /**
+     * Creates a virtual port.
+     *
+     * @param networkId  network identifier
+     * @param device     parent network element
+     * @param portNumber port number
+     * @param isEnabled  indicator whether the port is up and active
+     * @param realizedBy underling port which realizes this virtual port
+     */
+    public DefaultVirtualPort(NetworkId networkId, Device device, PortNumber portNumber,
+                              boolean isEnabled, ConnectPoint realizedBy) {
+        super((Element) device, portNumber, isEnabled, DefaultAnnotations.builder().build());
+        this.networkId = networkId;
+        this.realizedBy = realizedBy;
+    }
+
+    /**
+     * Returns network identifier.
+     *
+     * @return network identifier
+     */
+    public NetworkId networkId() {
+        return networkId;
+    }
+
+    @Override
+    public ConnectPoint realizedBy() {
+        return realizedBy;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(networkId, realizedBy);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultVirtualPort) {
+            DefaultVirtualPort that = (DefaultVirtualPort) obj;
+            return super.equals(that) &&
+                    Objects.equals(this.networkId, that.networkId) &&
+                    Objects.equals(this.number(), that.number()) &&
+                    Objects.equals(this.realizedBy, that.realizedBy);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("networkId", networkId).add("realizedBy", realizedBy).toString();
+    }
+
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/NetworkId.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/NetworkId.java
new file mode 100644
index 0000000..552e941
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/NetworkId.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+import java.util.Objects;
+
+/**
+ * Representation of network identity.
+ */
+@Beta
+public final class NetworkId extends Identifier<Long> {
+
+    /**
+     * Represents no network, or an unspecified network.
+     */
+    public static final NetworkId NONE = networkId(-1L);
+
+    /**
+     * Represents the underlying physical network.
+     */
+    public static final NetworkId PHYSICAL = networkId(0L);
+
+    /**
+     * Checks if the id is for virtual network.
+     *
+     * @return true if the id is for virtual network.
+     */
+    public final boolean isVirtualNetworkId() {
+        return (!Objects.equals(this, NONE) && !Objects.equals(this, PHYSICAL));
+    }
+
+    // Public construction is prohibited
+    private NetworkId(long id) {
+        super(id);
+    }
+
+
+    // Default constructor for serialization
+    protected NetworkId() {
+        super(-1L);
+    }
+
+    /**
+     * Creates a network id using the supplied backing id.
+     *
+     * @param id network id
+     * @return network identifier
+     */
+    public static NetworkId networkId(long id) {
+        return new NetworkId(id);
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualDevice.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualDevice.java
new file mode 100644
index 0000000..d4b098f
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualDevice.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.Device;
+
+/**
+ * Abstraction of a virtual device.
+ */
+@Beta
+public interface VirtualDevice extends VirtualElement, Device {
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualElement.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualElement.java
new file mode 100644
index 0000000..572d02d
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualElement.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Abstraction of a virtual element.
+ */
+@Beta
+public interface VirtualElement {
+
+    /**
+     * Returns the network identifier to which this virtual element belongs.
+     *
+     * @return network identifier
+     */
+    NetworkId networkId();
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualHost.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualHost.java
new file mode 100644
index 0000000..569d8e3
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualHost.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.Host;
+
+/**
+ * Abstraction of a virtual end-station host.
+ */
+@Beta
+public interface VirtualHost extends VirtualElement, Host {
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualLink.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualLink.java
new file mode 100644
index 0000000..6f68961
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualLink.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.net.Link;
+
+/**
+ * Abstraction of a virtual link.
+ */
+@Beta
+public interface VirtualLink extends VirtualElement, Link {
+    /**
+     * Returns the tunnel identifier to which this virtual link belongs.
+     *
+     * @return tunnel identifier
+     */
+    TunnelId tunnelId();
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetwork.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetwork.java
new file mode 100644
index 0000000..1cbbddb
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetwork.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.TenantId;
+
+/**
+ * Representation of a virtual network.
+ */
+@Beta
+public interface VirtualNetwork {
+
+    /**
+     * Returns the network identifier.
+     *
+     * @return network id
+     */
+    NetworkId id();
+
+    /**
+     * Returns the identifier of the tenant to which this virtual network belongs.
+     *
+     * @return tenant identifier
+     */
+    TenantId tenantId();
+
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java
new file mode 100644
index 0000000..bade4078
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import com.google.common.annotations.Beta;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TenantId;
+
+import java.util.Set;
+
+/**
+ * Service for managing the inventory of virtual networks.
+ */
+@Beta
+public interface VirtualNetworkAdminService extends VirtualNetworkService {
+
+    /**
+     * Registers the specified, externally generated tenant identifier.
+     *
+     * @param tenantId tenant identifier
+     */
+    void registerTenantId(TenantId tenantId);
+
+    /**
+     * Unregisters the specified, externally generated tenant identifier.
+     *
+     * @param tenantId tenant identifier
+     * @throws IllegalStateException if there are networks still owned by this tenant
+     */
+    void unregisterTenantId(TenantId tenantId);
+
+    /**
+     * Returns the set of tenant identifiers known to the system.
+     *
+     * @return set of known tenant identifiers
+     */
+    Set<TenantId> getTenantIds();
+
+    /**
+     * Creates a new virtual network for the specified tenant.
+     *
+     * @param tenantId tenant identifier
+     * @return newly created virtual network
+     */
+    VirtualNetwork createVirtualNetwork(TenantId tenantId);
+
+    /**
+     * Removes the specified virtual network and all its devices and links.
+     *
+     * @param networkId network identifier
+     */
+    void removeVirtualNetwork(NetworkId networkId);
+
+    /**
+     * Creates a new virtual device within the specified network. The device id
+     * must be unique within the bounds of the network.
+     *
+     * @param networkId network identifier
+     * @param deviceId  device identifier
+     * @return newly created virtual device
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    VirtualDevice createVirtualDevice(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Removes the specified virtual device and all its ports and affiliated links.
+     *
+     * @param networkId network identifier
+     * @param deviceId  device identifier
+     * @throws org.onlab.util.ItemNotFoundException if no such network or device found
+     */
+    void removeVirtualDevice(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Creates a new virtual host within the specified network. The host id
+     * must be unique within the bounds of the network.
+     *
+     * @param networkId network identifier
+     * @param hostId    host identifier
+     * @param mac       mac address
+     * @param vlan      vlan identifier
+     * @param location  host location
+     * @param ips       set of ip addresses
+     * @return newly created virtual host
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    VirtualHost createVirtualHost(NetworkId networkId, HostId hostId, MacAddress mac,
+                                  VlanId vlan, HostLocation location, Set<IpAddress> ips);
+
+    /**
+     * Removes the specified virtual host.
+     *
+     * @param networkId network identifier
+     * @param hostId  host identifier
+     * @throws org.onlab.util.ItemNotFoundException if no such network or host found
+     */
+    void removeVirtualHost(NetworkId networkId, HostId hostId);
+
+    /**
+     * Creates a new virtual link within the specified network.
+     *
+     * @param networkId  network identifier
+     * @param src        source connection point
+     * @param dst        destination connection point
+     * @return newly created virtual link
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    VirtualLink createVirtualLink(NetworkId networkId,
+                                  ConnectPoint src, ConnectPoint dst);
+
+    // TODO: Discuss whether we should provide an alternate createVirtualLink
+    // which is backed by a Path instead; I'm leaning towards not doing that.
+
+    /**
+     * Removes the specified virtual link.
+     *
+     * @param networkId network identifier
+     * @param src       source connection point
+     * @param dst       destination connection point
+     * @throws org.onlab.util.ItemNotFoundException if no such network or link found
+     */
+    void removeVirtualLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst);
+
+    /**
+     * Creates a new virtual port on the specified device.
+     *
+     * @param networkId  network identifier
+     * @param deviceId   virtual device identifier
+     * @param portNumber virtual port number
+     * @param realizedBy underlying physical port using which this virtual port is realized
+     * @return newly created port
+     * @throws org.onlab.util.ItemNotFoundException if no such network or device is found
+     */
+    VirtualPort createVirtualPort(NetworkId networkId, DeviceId deviceId,
+                                  PortNumber portNumber, ConnectPoint realizedBy);
+
+    /**
+     * Binds an existing virtual port on the specified device.
+     *
+     * @param networkId  network identifier
+     * @param deviceId   virtual device identifier
+     * @param portNumber virtual port number
+     * @param realizedBy underlying physical port using which this virtual port is realized
+     * @throws org.onlab.util.ItemNotFoundException if no such network or device is found
+     */
+    void bindVirtualPort(NetworkId networkId, DeviceId deviceId,
+                                  PortNumber portNumber, ConnectPoint realizedBy);
+
+    /**
+     * Updates port state of an existing virtual port on the specified device.
+     *
+     * @param networkId  network identifier
+     * @param deviceId   virtual device identifier
+     * @param portNumber virtual port number
+     * @param isEnabled  indicator whether the port is up and active
+     * @throws org.onlab.util.ItemNotFoundException if no such network or device is found
+     */
+    void updatePortState(NetworkId networkId, DeviceId deviceId,
+                                  PortNumber portNumber, boolean isEnabled);
+
+    /**
+     * Removes the specified virtual port.
+     *
+     * @param networkId  network identifier
+     * @param deviceId   device identifier
+     * @param portNumber port number
+     * @throws org.onlab.util.ItemNotFoundException if no such network or port found
+     */
+    void removeVirtualPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkEvent.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkEvent.java
new file mode 100644
index 0000000..3f96496
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkEvent.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import org.onosproject.event.AbstractEvent;
+
+/**
+ * Describes virtual network event.
+ */
+public class VirtualNetworkEvent extends AbstractEvent<VirtualNetworkEvent.Type, NetworkId> {
+
+    /**
+     * Type of virtual network events.
+     */
+    public enum Type {
+        /**
+         * Signifies that a new tenant identifier was registered.
+         */
+        TENANT_REGISTERED,
+        /**
+         * Signifies that a tenant identifier was unregistered.
+         */
+        TENANT_UNREGISTERED,
+        /**
+         * Signifies that a new virtual network was added.
+         */
+        NETWORK_ADDED,
+        /**
+         * Signifies that a virtual network was updated.
+         */
+        NETWORK_UPDATED,
+        /**
+         * Signifies that a virtual network was removed.
+         */
+        NETWORK_REMOVED,
+        /**
+         * Signifies that a new virtual network device was added.
+         */
+        VIRTUAL_DEVICE_ADDED,
+        /**
+         * Signifies that a virtual network device was updated.
+         */
+        VIRTUAL_DEVICE_UPDATED,
+        /**
+         * Signifies that a virtual network device was removed.
+         */
+        VIRTUAL_DEVICE_REMOVED,
+        /**
+         * Signifies that a new virtual network port was added.
+         */
+        VIRTUAL_PORT_ADDED,
+        /**
+         * Signifies that a virtual network port was updated.
+         */
+        VIRTUAL_PORT_UPDATED,
+        /**
+         * Signifies that a virtual network port was removed.
+         */
+        VIRTUAL_PORT_REMOVED
+    }
+
+    private final VirtualDevice virtualDevice;
+    private final VirtualPort virtualPort;
+
+    /**
+     * Creates an event of a given type and for the specified subject.
+     *
+     * @param type        event type
+     * @param subject     event subject
+     */
+    public VirtualNetworkEvent(Type type, NetworkId subject) {
+        this(type, subject, null, null);
+    }
+
+    /**
+     * Creates an event of a given type and for the specified subject and the
+     * virtual device.
+     *
+     * @param type          event type
+     * @param subject       event subject
+     * @param virtualDevice virtual device
+     */
+    public VirtualNetworkEvent(Type type, NetworkId subject, VirtualDevice virtualDevice) {
+        this(type, subject, virtualDevice, null);
+    }
+
+    /**
+     * Creates an event of a given type and for the specified subject, virtual device and
+     * virtual port.
+     *
+     * @param type          event type
+     * @param subject       event subject
+     * @param virtualDevice virtual device
+     * @param virtualPort   virtual port
+     */
+    public VirtualNetworkEvent(Type type, NetworkId subject, VirtualDevice virtualDevice,
+                                VirtualPort virtualPort) {
+        super(type, subject);
+        this.virtualDevice = virtualDevice;
+        this.virtualPort = virtualPort;
+    }
+
+    /**
+     * Creates an event of a given type and for the specified subject and time.
+     *
+     * @param type        event type
+     * @param subject     event subject
+     * @param time        occurrence time
+     */
+    public VirtualNetworkEvent(Type type, NetworkId subject, long time) {
+        this(type, subject, null, null, time);
+    }
+
+    /**
+     * Creates an event of a given type and for the specified subject, virtual device and time.
+     *
+     * @param type          event type
+     * @param subject       event subject
+     * @param virtualDevice virtual device
+     * @param time          occurrence time
+     */
+    public VirtualNetworkEvent(Type type, NetworkId subject, VirtualDevice virtualDevice,
+                               long time) {
+        this(type, subject, virtualDevice, null, time);
+    }
+
+    /**
+     * Creates an event of a given type and for the specified subject, virtual port and time.
+     *
+     * @param type          device event type
+     * @param subject       event subject
+     * @param virtualPort   virtual port
+     * @param time          occurrence time
+     */
+    public VirtualNetworkEvent(Type type, NetworkId subject, VirtualPort virtualPort,
+                               long time) {
+        this(type, subject, null, virtualPort, time);
+    }
+
+    /**
+     * Creates an event of a given type and for the specified subject, virtual device,
+     * virtual port and time.
+     *
+     * @param type          device event type
+     * @param subject       event subject
+     * @param virtualDevice virtual device
+     * @param virtualPort   virtual port
+     * @param time          occurrence time
+     */
+    private VirtualNetworkEvent(Type type, NetworkId subject, VirtualDevice virtualDevice,
+                                VirtualPort virtualPort, long time) {
+        super(type, subject, time);
+        this.virtualDevice = virtualDevice;
+        this.virtualPort = virtualPort;
+    }
+
+    /**
+     * Returns virtual device affected by event - may be null (for events relating to
+     * tenants and virtual networks).
+     *
+     * @return virtual device
+     */
+    public VirtualDevice virtualDevice() {
+        return virtualDevice;
+    }
+
+    /**
+     * Returns virtual port affected by event - may be null (for events relating to
+     * tenants, virtual networks and virtual devices).
+     *
+     * @return virtual port
+     */
+    public VirtualPort virtualPort() {
+        return virtualPort;
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkFlowObjectiveStore.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkFlowObjectiveStore.java
new file mode 100644
index 0000000..c118958
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkFlowObjectiveStore.java
@@ -0,0 +1,75 @@
+/*
+ * 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;
+
+import org.onosproject.net.behaviour.NextGroup;
+import org.onosproject.net.flowobjective.FlowObjectiveStoreDelegate;
+import org.onosproject.net.flowobjective.ObjectiveEvent;
+
+import java.util.Map;
+
+/**
+ * The flow objective store for virtual networks.
+ */
+public interface VirtualNetworkFlowObjectiveStore
+        extends VirtualStore<ObjectiveEvent, FlowObjectiveStoreDelegate> {
+
+    /**
+     * Adds a NextGroup to the store, by mapping it to the nextId as key,
+     * and replacing any previous mapping.
+     *
+     * @param networkId a virtual network identifier
+     * @param nextId an integer
+     * @param group a next group opaque object
+     */
+    void putNextGroup(NetworkId networkId, Integer nextId, NextGroup group);
+
+    /**
+     * Fetch a next group from the store.
+     *
+     * @param networkId a virtual network identifier
+     * @param nextId an integer used as key
+     * @return a next group, or null if group was not found
+     */
+    NextGroup getNextGroup(NetworkId networkId, Integer nextId);
+
+    /**
+     * Remove a next group mapping from the store.
+     *
+     * @param networkId a virtual network identifier
+     * @param nextId  the key to remove from the store.
+     * @return the next group which mapped to the nextId and is now removed, or
+     *          null if no group mapping existed in the store
+     */
+    NextGroup removeNextGroup(NetworkId networkId, Integer nextId);
+
+    /**
+     * Fetch all groups from the store and their mapping to nextIds.
+     *
+     * @param networkId a virtual network identifier
+     * @return a map that represents the current snapshot of Next-ids to NextGroups
+     */
+    Map<Integer, NextGroup> getAllGroups(NetworkId networkId);
+
+    /**
+     * Allocates a next objective id. This id is globally unique.
+     *
+     * @param networkId a virtual network identifier
+     * @return an integer
+     */
+    int allocateNextId(NetworkId networkId);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkFlowRuleStore.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkFlowRuleStore.java
new file mode 100644
index 0000000..6b532c3
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkFlowRuleStore.java
@@ -0,0 +1,153 @@
+/*
+ * 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;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchEvent;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleStoreDelegate;
+import org.onosproject.net.flow.TableStatisticsEntry;
+
+import java.util.List;
+
+/**
+ * Manages inventory of flow rules for virtual networks;
+ * not intended for direct use.
+ */
+public interface VirtualNetworkFlowRuleStore
+        extends VirtualStore<FlowRuleBatchEvent, FlowRuleStoreDelegate> {
+    /**
+     * Returns the number of flow rule in the store.
+     *
+     * @param networkId virtual network identifier
+     * @return number of flow rules
+     */
+    int getFlowRuleCount(NetworkId networkId);
+
+    /**
+     * Returns the stored flow.
+     *
+     * @param networkId virtual network identifier
+     * @param rule the rule to look for
+     * @return a flow rule
+     */
+    FlowEntry getFlowEntry(NetworkId networkId, FlowRule rule);
+
+    /**
+     * Returns the flow entries associated with a device.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId the device ID
+     * @return the flow entries
+     */
+    Iterable<FlowEntry> getFlowEntries(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Stores a batch of flow rules.
+     *
+     * @param networkId virtual network identifier
+     * @param batchOperation batch of flow rules.
+     *           A batch can contain flow rules for a single device only.
+     *
+     */
+    void storeBatch(NetworkId networkId, FlowRuleBatchOperation batchOperation);
+
+    /**
+     * Invoked on the completion of a storeBatch operation.
+     *
+     * @param networkId virtual network identifier
+     * @param event flow rule batch event
+     */
+    void batchOperationComplete(NetworkId networkId, FlowRuleBatchEvent event);
+
+    /**
+     * Marks a flow rule for deletion. Actual deletion will occur
+     * when the provider indicates that the flow has been removed.
+     *
+     * @param networkId virtual network identifier
+     * @param rule the flow rule to delete
+     */
+    void deleteFlowRule(NetworkId networkId, FlowRule rule);
+
+    /**
+     * Stores a new flow rule, or updates an existing entry.
+     *
+     * @param networkId virtual network identifier
+     * @param rule the flow rule to add or update
+     * @return flow_added event, or null if just an update
+     */
+    FlowRuleEvent addOrUpdateFlowRule(NetworkId networkId, FlowEntry rule);
+
+    /**
+     * Removes an existing flow entry.
+     *
+     * @param rule the flow entry to remove
+     * @param networkId virtual network identifier
+     * @return flow_removed event, or null if nothing removed
+     */
+    FlowRuleEvent removeFlowRule(NetworkId networkId, FlowEntry rule);
+
+    /**
+     * Marks a flow rule as PENDING_ADD during retry.
+     *
+     * Emits flow_update event if the state is changed
+     *
+     * @param networkId virtual network identifier
+     * @param rule the flow rule that is retrying
+     * @return flow_updated event, or null if nothing updated
+     */
+    FlowRuleEvent pendingFlowRule(NetworkId networkId, FlowEntry rule);
+
+    /**
+     * Removes all flow entries of given device from store.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId device id
+     */
+    default void purgeFlowRule(NetworkId networkId, DeviceId deviceId) {}
+
+    /**
+     * Removes all flow entries from store.
+     *
+     * @param networkId virtual network identifier
+     */
+    void purgeFlowRules(NetworkId networkId);
+
+    /**
+     * Updates the flow table statistics of the specified device using
+     * the given statistics.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId    device identifier
+     * @param tableStats   list of table statistics
+     * @return ready to send event describing what occurred;
+     */
+    FlowRuleEvent updateTableStatistics(NetworkId networkId, DeviceId deviceId,
+                                        List<TableStatisticsEntry> tableStats);
+
+    /**
+     * Returns the flow table statistics associated with a device.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId the device ID
+     * @return the flow table statistics
+     */
+    Iterable<TableStatisticsEntry> getTableStatistics(NetworkId networkId, DeviceId deviceId);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkGroupStore.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkGroupStore.java
new file mode 100644
index 0000000..d080524
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkGroupStore.java
@@ -0,0 +1,231 @@
+/*
+ * 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;
+
+import org.onosproject.core.GroupId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupEvent;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupOperation;
+import org.onosproject.net.group.GroupStoreDelegate;
+
+import java.util.Collection;
+
+/**
+ * Manages inventory of groups per virtual network and virtual device;
+ * not intended for direct use.
+ */
+public interface VirtualNetworkGroupStore
+        extends VirtualStore<GroupEvent, GroupStoreDelegate> {
+
+    enum UpdateType {
+        /**
+         * Modify existing group entry by adding provided information.
+         */
+        ADD,
+        /**
+         * Modify existing group by removing provided information from it.
+         */
+        REMOVE,
+        /**
+         * Modify existing group entry by setting the provided information,
+         * overwriting the previous group entry entirely.
+         */
+        SET
+    }
+
+    /**
+     * Returns the number of groups for the specified virtual device in the store.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId the device ID
+     * @return number of groups for the specified device
+     */
+    int getGroupCount(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Returns the groups associated with a virtual device.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId the device ID
+     * @return the group entries
+     */
+    Iterable<Group> getGroups(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Returns the stored group entry in a virtual network.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId the device ID
+     * @param appCookie the group key
+     * @return a group associated with the key
+     */
+    Group getGroup(NetworkId networkId, DeviceId deviceId, GroupKey appCookie);
+
+    /**
+     * Returns the stored group entry for an id.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId the device ID
+     * @param groupId the group identifier
+     * @return a group associated with the key
+     */
+    Group getGroup(NetworkId networkId, DeviceId deviceId, GroupId groupId);
+
+    /**
+     * Stores a new group entry using the information from group description
+     * for a virtual network.
+     *
+     * @param networkId the virtual network ID
+     * @param groupDesc group description to be used to store group entry
+     */
+    void storeGroupDescription(NetworkId networkId, GroupDescription groupDesc);
+
+    /**
+     * Updates the existing group entry with the information
+     * from group description.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId the device ID
+     * @param oldAppCookie the current group key
+     * @param type update type
+     * @param newBuckets group buckets for updates
+     * @param newAppCookie optional new group key
+     */
+    void updateGroupDescription(NetworkId networkId,
+                                DeviceId deviceId,
+                                GroupKey oldAppCookie,
+                                UpdateType type,
+                                GroupBuckets newBuckets,
+                                GroupKey newAppCookie);
+
+    /**
+     * Triggers deleting the existing group entry.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId the device ID
+     * @param appCookie the group key
+     */
+    void deleteGroupDescription(NetworkId networkId,
+                                DeviceId deviceId,
+                                GroupKey appCookie);
+
+    /**
+     * Stores a new group entry, or updates an existing entry.
+     *
+     * @param networkId the virtual network ID
+     * @param group group entry
+     */
+    void addOrUpdateGroupEntry(NetworkId networkId, Group group);
+
+    /**
+     * Removes the group entry from store.
+     *
+     * @param networkId the virtual network ID
+     * @param group group entry
+     */
+    void removeGroupEntry(NetworkId networkId, Group group);
+
+    /**
+     * Removes all group entries of given device from store.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId device id
+     */
+    void purgeGroupEntry(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Removes all group entries from store.
+     *
+     * @param networkId the virtual network ID
+     */
+    default void purgeGroupEntries(NetworkId networkId) {}
+
+    /**
+     * A group entry that is present in switch but not in the store.
+     *
+     * @param networkId the virtual network ID
+     * @param group group entry
+     */
+    void addOrUpdateExtraneousGroupEntry(NetworkId networkId, Group group);
+
+    /**
+     * Remove the group entry from extraneous database.
+     *
+     * @param networkId the virtual network ID
+     * @param group group entry
+     */
+    void removeExtraneousGroupEntry(NetworkId networkId, Group group);
+
+    /**
+     * Returns the extraneous groups associated with a device.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId the device ID
+     *
+     * @return the extraneous group entries
+     */
+    Iterable<Group> getExtraneousGroups(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Indicates the first group audit is completed.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId the device ID
+     * @param completed initial audit status
+     */
+    void deviceInitialAuditCompleted(NetworkId networkId, DeviceId deviceId, boolean completed);
+
+    /**
+     * Retrieves the initial group audit status for a device.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId the device ID
+     *
+     * @return initial group audit status
+     */
+    boolean deviceInitialAuditStatus(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Indicates the group operations failed.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId the device ID
+     * @param operation the group operation failed
+     */
+    void groupOperationFailed(NetworkId networkId, DeviceId deviceId, GroupOperation operation);
+
+    /**
+     * Submits the group metrics to store for a given device ID.
+     *
+     * @param networkId the virtual network ID
+     * @param deviceId the device ID
+     * @param groupEntries the group entries as received from southbound
+     */
+    void pushGroupMetrics(NetworkId networkId, DeviceId deviceId, Collection<Group> groupEntries);
+
+    /**
+     * Indicates failover within a failover group.
+     *
+     * @param networkId the virtual network ID
+     * @param failoverGroups groups to notify
+     */
+    void notifyOfFailovers(NetworkId networkId, Collection<Group> failoverGroups);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkIntent.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkIntent.java
new file mode 100644
index 0000000..817db21
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkIntent.java
@@ -0,0 +1,260 @@
+/*
+ * 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;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.ResourceGroup;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.ConnectivityIntent;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Key;
+
+import java.util.Collections;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Abstraction of VirtualNetworkIntent connectivity.
+ */
+@Beta
+public final class VirtualNetworkIntent extends ConnectivityIntent {
+
+    private final NetworkId networkId;
+    private final ConnectPoint ingressPoint;
+    private final ConnectPoint egressPoint;
+
+    private static final String NETWORK_ID_NULL = "Network ID cannot be null";
+
+    /**
+     * Returns a new point to point intent builder. The application id,
+     * ingress point and egress point are required fields.  If they are
+     * not set by calls to the appropriate methods, an exception will
+     * be thrown.
+     *
+     * @return point to point builder
+     */
+    public static VirtualNetworkIntent.Builder builder() {
+        return new VirtualNetworkIntent.Builder();
+    }
+
+    /**
+     * Builder of a point to point intent.
+     */
+    public static final class Builder extends ConnectivityIntent.Builder {
+        NetworkId networkId;
+        ConnectPoint ingressPoint;
+        ConnectPoint egressPoint;
+
+        /**
+         * Builder constructor.
+         */
+        private Builder() {
+            // Hide constructor
+        }
+
+        @Override
+        public Builder appId(ApplicationId appId) {
+            return (Builder) super.appId(appId);
+        }
+
+        @Override
+        public Builder key(Key key) {
+            return (Builder) super.key(key);
+        }
+
+        @Override
+        public Builder selector(TrafficSelector selector) {
+            return (Builder) super.selector(selector);
+        }
+
+        @Override
+        public Builder treatment(TrafficTreatment treatment) {
+            return (Builder) super.treatment(treatment);
+        }
+
+        @Override
+        public Builder constraints(List<Constraint> constraints) {
+            return (Builder) super.constraints(constraints);
+        }
+
+        @Override
+        public Builder priority(int priority) {
+            return (Builder) super.priority(priority);
+        }
+
+        @Override
+        public Builder resourceGroup(ResourceGroup resourceGroup) {
+            return (Builder) super.resourceGroup(resourceGroup);
+        }
+
+        /**
+         * Sets the virtual network of the virtual network intent.
+         *
+         * @param networkId virtual network identifier
+         * @return this builder
+         */
+        public VirtualNetworkIntent.Builder networkId(NetworkId networkId) {
+            this.networkId = networkId;
+            return this;
+        }
+
+        /**
+         * Sets the ingress point of the virtual network intent that will be built.
+         *
+         * @param ingressPoint ingress connect point
+         * @return this builder
+         */
+        public VirtualNetworkIntent.Builder ingressPoint(ConnectPoint ingressPoint) {
+            this.ingressPoint = ingressPoint;
+            return this;
+        }
+
+        /**
+         * Sets the egress point of the virtual network intent that will be built.
+         *
+         * @param egressPoint egress connect point
+         * @return this builder
+         */
+        public VirtualNetworkIntent.Builder egressPoint(ConnectPoint egressPoint) {
+            this.egressPoint = egressPoint;
+            return this;
+        }
+
+        /**
+         * Builds a virtual network intent from the accumulated parameters.
+         *
+         * @return virtual network intent
+         */
+        public VirtualNetworkIntent build() {
+
+            return new VirtualNetworkIntent(
+                    networkId,
+                    appId,
+                    key,
+                    selector,
+                    treatment,
+                    ingressPoint,
+                    egressPoint,
+                    constraints,
+                    priority,
+                    resourceGroup
+            );
+        }
+    }
+
+
+    /**
+     * Creates a new point-to-point intent with the supplied ingress/egress
+     * ports and constraints.
+     *
+     * @param networkId    virtual network identifier
+     * @param appId        application identifier
+     * @param key          key of the intent
+     * @param selector     traffic selector
+     * @param treatment    treatment
+     * @param ingressPoint ingress port
+     * @param egressPoint  egress port
+     * @param constraints  optional list of constraints
+     * @param priority     priority to use for flows generated by this intent
+     * @throws NullPointerException if {@code ingressPoint} or
+     *                              {@code egressPoints} or {@code appId} is null.
+     */
+    private VirtualNetworkIntent(NetworkId networkId,
+                                 ApplicationId appId,
+                                 Key key,
+                                 TrafficSelector selector,
+                                 TrafficTreatment treatment,
+                                 ConnectPoint ingressPoint,
+                                 ConnectPoint egressPoint,
+                                 List<Constraint> constraints,
+                                 int priority,
+                                 ResourceGroup resourceGroup) {
+        super(appId, key, Collections.emptyList(), selector, treatment, constraints,
+              priority, resourceGroup);
+
+        checkNotNull(networkId, NETWORK_ID_NULL);
+        checkArgument(!ingressPoint.equals(egressPoint),
+                      "ingress and egress should be different (ingress: %s, egress: %s)", ingressPoint, egressPoint);
+
+        this.networkId = networkId;
+        this.ingressPoint = checkNotNull(ingressPoint);
+        this.egressPoint = checkNotNull(egressPoint);
+    }
+
+    /**
+     * Constructor for serializer.
+     */
+    protected VirtualNetworkIntent() {
+        super();
+        this.networkId = null;
+        this.ingressPoint = null;
+        this.egressPoint = null;
+    }
+
+    /**
+     * Returns the virtual network identifier.
+     *
+     * @return network identifier
+     */
+    public NetworkId networkId() {
+        return networkId;
+    }
+
+    /**
+     * Returns the port on which the ingress traffic should be connected to
+     * the egress.
+     *
+     * @return ingress port
+     */
+    public ConnectPoint ingressPoint() {
+        return ingressPoint;
+    }
+
+    /**
+     * Returns the port on which the traffic should egress.
+     *
+     * @return egress port
+     */
+    public ConnectPoint egressPoint() {
+        return egressPoint;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("networkId", networkId)
+                .add("id", id())
+                .add("key", key())
+                .add("appId", appId())
+                .add("priority", priority())
+                .add("resources", resources())
+                .add("selector", selector())
+                .add("treatment", treatment())
+                .add("ingress", ingressPoint)
+                .add("egress", egressPoint)
+                .add("constraints", constraints())
+                .add("resourceGroup", resourceGroup())
+                .toString();
+    }
+
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkIntentStore.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkIntentStore.java
new file mode 100644
index 0000000..f8b42c1
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkIntentStore.java
@@ -0,0 +1,170 @@
+/*
+ * 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;
+
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.IntentStoreDelegate;
+import org.onosproject.net.intent.Key;
+
+import java.util.List;
+
+public interface VirtualNetworkIntentStore
+        extends VirtualStore<IntentEvent, IntentStoreDelegate> {
+
+    /**
+     * Returns the number of intents in the store.
+     *
+     * @param networkId the virtual network identifier
+     * @return the number of intents in the store
+     */
+    long getIntentCount(NetworkId networkId);
+
+    /**
+     * Returns an iterable of all intents in the store.
+     *
+     * @param networkId the virtual network identifier
+     * @return iterable  of all intents
+     */
+    Iterable<Intent> getIntents(NetworkId networkId);
+
+    /**
+     * Returns an iterable of all intent data objects in the store.
+     *
+     * @param networkId the virtual network identifier
+     * @param localOnly should only intents for which this instance is master
+     *                  be returned
+     * @param olderThan specified duration in milliseconds (0 for "now")
+     * @return iterable of all intent data objects
+     */
+    Iterable<IntentData> getIntentData(NetworkId networkId, boolean localOnly,
+                                       long olderThan);
+
+    /**
+     * Returns the state of the specified intent.
+     *
+     * @param networkId the virtual network identifier
+     * @param intentKey intent identification
+     * @return current intent state
+     */
+    IntentState getIntentState(NetworkId networkId, Key intentKey);
+
+    /**
+     * Returns the list of the installable events associated with the specified
+     * original intent.
+     *
+     * @param networkId the virtual network identifier
+     * @param intentKey original intent identifier
+     * @return compiled installable intents, or null if no installables exist
+     */
+    List<Intent> getInstallableIntents(NetworkId networkId, Key intentKey);
+
+    /**
+     * Writes an IntentData object to the store.
+     *
+     * @param networkId the virtual network identifier
+     * @param newData new intent data to write
+     */
+    void write(NetworkId networkId, IntentData newData);
+
+    /**
+     * Writes a batch of IntentData objects to the store. A batch has no
+     * semantics, this is simply a convenience API.
+     *
+     * @param networkId the virtual network identifier
+     * @param updates collection of intent data objects to write
+     */
+    void batchWrite(NetworkId networkId, Iterable<IntentData> updates);
+
+    /**
+     * Returns the intent with the specified identifier.
+     *
+     * @param networkId the virtual network identifier
+     * @param key key
+     * @return intent or null if not found
+     */
+    Intent getIntent(NetworkId networkId, Key key);
+
+    /**
+     * Returns the intent data object associated with the specified key.
+     *
+     * @param networkId the virtual network identifier
+     * @param key key to look up
+     * @return intent data object
+     */
+    IntentData getIntentData(NetworkId networkId, Key key);
+
+    /**
+     * Adds a new operation, which should be persisted and delegated.
+     *
+     * @param networkId the virtual network identifier
+     * @param intent operation
+     */
+    void addPending(NetworkId networkId, IntentData intent);
+
+    /**
+     * Checks to see whether the calling instance is the master for processing
+     * this intent, or more specifically, the key contained in this intent.
+     *
+     * @param networkId the virtual network identifier
+     * @param intentKey intentKey to check
+     * @return true if master; false, otherwise
+     */
+    //TODO better name
+    boolean isMaster(NetworkId networkId, Key intentKey);
+
+    /**
+     * Returns the intent requests pending processing.
+     *
+     * @param networkId the virtual network identifier
+     * @return pending intents
+     */
+    Iterable<Intent> getPending(NetworkId networkId);
+
+    /**
+     * Returns the intent data objects that are pending processing.
+     *
+     * @param networkId the virtual network identifier
+     * @return pending intent data objects
+     */
+    Iterable<IntentData> getPendingData(NetworkId networkId);
+
+    /**
+     * Returns the intent data object that are pending processing for a specfied
+     * key.
+     *
+     * @param networkId the virtual network identifier
+     * @param intentKey key to look up
+     * @return pending intent data object
+     */
+    IntentData getPendingData(NetworkId networkId, Key intentKey);
+
+    /**
+     * Returns the intent data objects that are pending processing for longer
+     * than the specified duration.
+     *
+     * @param networkId the virtual network identifier
+     * @param localOnly  should only intents for which this instance is master
+     *                   be returned
+     * @param olderThan specified duration in milliseconds (0 for "now")
+     * @return pending intent data objects
+     */
+    Iterable<IntentData> getPendingData(NetworkId networkId, boolean localOnly, long olderThan);
+
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkListener.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkListener.java
new file mode 100644
index 0000000..cc6d663
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkListener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Represents entity capable of receiving virtual network events.
+ */
+public interface VirtualNetworkListener extends EventListener<VirtualNetworkEvent> {
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkMastershipStore.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkMastershipStore.java
new file mode 100644
index 0000000..31fdfcd
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkMastershipStore.java
@@ -0,0 +1,152 @@
+/*
+ * 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;
+
+import org.onosproject.cluster.NodeId;
+import org.onosproject.cluster.RoleInfo;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipInfo;
+import org.onosproject.mastership.MastershipStoreDelegate;
+import org.onosproject.mastership.MastershipTerm;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Manages inventory of mastership roles for devices, across controller
+ * instances for virtual networks; not intended for direct use.
+ */
+public interface VirtualNetworkMastershipStore
+        extends VirtualStore<MastershipEvent, MastershipStoreDelegate> {
+
+    // three things to map: NodeId, DeviceId, MastershipRole
+
+    /**
+     * Requests role of the local node for the specified device.
+     *
+     * @param networkId the virtual network identifier
+     * @param deviceId  the device identifier
+     * @return established or newly negotiated mastership role
+     */
+    CompletableFuture<MastershipRole> requestRole(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Returns the role of a device for a specific controller instance.
+     *
+     * @param networkId virtual network identifier
+     * @param nodeId    the instance identifier
+     * @param deviceId  the device identifiers
+     * @return the role
+     */
+    MastershipRole getRole(NetworkId networkId, NodeId nodeId, DeviceId deviceId);
+
+    /**
+     * Returns the master for a device.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId  the device identifier
+     * @return the instance identifier of the master
+     */
+    NodeId getMaster(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Returns the master and backup nodes for a device.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId  the device identifier
+     * @return a RoleInfo containing controller IDs
+     */
+    RoleInfo getNodes(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Returns the mastership info for a device.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId  the device identifier
+     * @return the mastership info
+     */
+    MastershipInfo getMastership(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Returns the devices that a controller instance is master of.
+     *
+     * @param networkId virtual network identifier
+     * @param nodeId    the instance identifier
+     * @return a set of device identifiers
+     */
+    Set<DeviceId> getDevices(NetworkId networkId, NodeId nodeId);
+
+
+    /**
+     * Sets a device's role for a specified controller instance.
+     *
+     * @param networkId virtual network identifier
+     * @param nodeId    controller instance identifier
+     * @param deviceId  device identifier
+     * @return a mastership event
+     */
+    CompletableFuture<MastershipEvent> setMaster(NetworkId networkId,
+                                                 NodeId nodeId, DeviceId deviceId);
+
+    /**
+     * Returns the current master and number of past mastership hand-offs
+     * (terms) for a device.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId  the device identifier
+     * @return the current master's ID and the term value for device, or null
+     */
+    MastershipTerm getTermFor(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Sets a controller instance's mastership role to STANDBY for a device.
+     * If the role is MASTER, another controller instance will be selected
+     * as a candidate master.
+     *
+     * @param networkId virtual network identifier
+     * @param nodeId    the controller instance identifier
+     * @param deviceId  device to revoke mastership role for
+     * @return a mastership event
+     */
+    CompletableFuture<MastershipEvent> setStandby(NetworkId networkId,
+                                                  NodeId nodeId, DeviceId deviceId);
+
+    /**
+     * Allows a controller instance to give up its current role for a device.
+     * If the role is MASTER, another controller instance will be selected
+     * as a candidate master.
+     *
+     * @param networkId virtual network identifier
+     * @param nodeId    the controller instance identifier
+     * @param deviceId  device to revoke mastership role for
+     * @return a mastership event
+     */
+    CompletableFuture<MastershipEvent> relinquishRole(NetworkId networkId,
+                                                      NodeId nodeId, DeviceId deviceId);
+
+    /**
+     * Removes all the roles for the specified controller instance.
+     * If the role was MASTER, another controller instance will be selected
+     * as a candidate master.
+     *
+     * @param networkId virtual network identifier
+     * @param nodeId    the controller instance identifier
+     */
+    void relinquishAllRole(NetworkId networkId, NodeId nodeId);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkMeterStore.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkMeterStore.java
new file mode 100644
index 0000000..954f66b
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkMeterStore.java
@@ -0,0 +1,135 @@
+/*
+ * 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;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterEvent;
+import org.onosproject.net.meter.MeterFailReason;
+import org.onosproject.net.meter.MeterFeatures;
+import org.onosproject.net.meter.MeterFeaturesKey;
+import org.onosproject.net.meter.MeterKey;
+import org.onosproject.net.meter.MeterOperation;
+import org.onosproject.net.meter.MeterStoreDelegate;
+import org.onosproject.net.meter.MeterStoreResult;
+
+import java.util.Collection;
+import java.util.concurrent.CompletableFuture;
+
+public interface VirtualNetworkMeterStore
+        extends VirtualStore<MeterEvent, MeterStoreDelegate> {
+
+    /**
+     * Adds a meter to the store.
+     *
+     * @param networkId a virtual network identifier
+     * @param meter a meter
+     * @return a future indicating the result of the store operation
+     */
+    CompletableFuture<MeterStoreResult> storeMeter(NetworkId networkId, Meter meter);
+
+    /**
+     * Deletes a meter from the store.
+     *
+     * @param networkId a virtual network identifier
+     * @param meter a meter
+     * @return a future indicating the result of the store operation
+     */
+    CompletableFuture<MeterStoreResult> deleteMeter(NetworkId networkId, Meter meter);
+
+
+    /**
+     * Adds the meter features to the store.
+     *
+     * @param networkId a virtual network identifier
+     * @param meterfeatures the meter features
+     * @return the result of the store operation
+     */
+    MeterStoreResult storeMeterFeatures(NetworkId networkId, MeterFeatures meterfeatures);
+
+    /**
+     * Deletes the meter features from the store.
+     *
+     * @param networkId a virtual network identifier
+     * @param deviceId the device id
+     * @return a future indicating the result of the store operation
+     */
+    MeterStoreResult deleteMeterFeatures(NetworkId networkId, DeviceId deviceId);
+
+
+    /**
+     * Updates a meter whose meter id is the same as the passed meter.
+     *
+     * @param networkId a virtual network identifier
+     * @param meter a new meter
+     * @return a future indicating the result of the store operation
+     */
+    CompletableFuture<MeterStoreResult> updateMeter(NetworkId networkId, Meter meter);
+
+    /**
+     * Updates a given meter's state with the provided state.
+     *
+     * @param networkId a virtual network identifier
+     * @param meter a meter
+     */
+    void updateMeterState(NetworkId networkId, Meter meter);
+
+    /**
+     * Obtains a meter matching the given meter key.
+     *
+     * @param networkId a virtual network identifier
+     * @param key a meter key
+     * @return a meter
+     */
+    Meter getMeter(NetworkId networkId, MeterKey key);
+
+    /**
+     * Returns all meters stored in the store.
+     *
+     * @param networkId a virtual network identifier
+     * @return a collection of meters
+     */
+    Collection<Meter> getAllMeters(NetworkId networkId);
+
+    /**
+     * Update the store by deleting the failed meter.
+     * Notifies the delegate that the meter failed to allow it
+     * to nofity the app.
+     *
+     * @param networkId a virtual network identifier
+     * @param op a failed meter operation
+     * @param reason a failure reason
+     */
+    void failedMeter(NetworkId networkId, MeterOperation op, MeterFailReason reason);
+
+    /**
+     * Delete this meter immediately.
+     *
+     * @param networkId a virtual network identifier
+     * @param m a meter
+     */
+    void deleteMeterNow(NetworkId networkId, Meter m);
+
+    /**
+     * Retrieve maximum meters available for the device.
+     *
+     * @param networkId a virtual network identifier
+     * @param key the meter features key
+     * @return the maximum number of meters supported by the device
+     */
+    long getMaxMeters(NetworkId networkId, MeterFeaturesKey key);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkPacketStore.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkPacketStore.java
new file mode 100644
index 0000000..4cf5cb9
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkPacketStore.java
@@ -0,0 +1,61 @@
+/*
+ * 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;
+
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketEvent;
+import org.onosproject.net.packet.PacketRequest;
+import org.onosproject.net.packet.PacketStoreDelegate;
+
+import java.util.List;
+
+public interface VirtualNetworkPacketStore
+        extends VirtualStore<PacketEvent, PacketStoreDelegate> {
+    /**
+     * Decides which instance should emit the packet and forwards the packet to
+     * that instance. The relevant PacketManager is notified via the
+     * PacketStoreDelegate that it should emit the packet.
+     *
+     * @param networkId a virtual network identifier
+     * @param packet the packet to emit
+     */
+    void emit(NetworkId networkId, OutboundPacket packet);
+
+    /**
+     * Requests intercept of packets that match the given selector.
+     *
+     * @param networkId a virtual network identifier
+     * @param request a packet request
+     */
+    void requestPackets(NetworkId networkId, PacketRequest request);
+
+    /**
+     * Cancels intercept of packets that match the given selector.
+     *
+     * @param networkId a virtual network identifier
+     * @param request a packet request
+     */
+    void cancelPackets(NetworkId networkId, PacketRequest request);
+
+    /**
+     * Obtains all existing requests in the system.
+     *
+     * @param networkId a virtual network identifier
+     * @return list of packet requests in order of priority
+     */
+    List<PacketRequest> existingRequests(NetworkId networkId);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java
new file mode 100644
index 0000000..d0e4fd1
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import com.google.common.annotations.Beta;
+import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.event.ListenerService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.TenantId;
+
+import java.util.Set;
+
+/**
+ * Service for querying virtual network inventory.
+ */
+@Beta
+public interface VirtualNetworkService
+        extends ListenerService<VirtualNetworkEvent, VirtualNetworkListener> {
+
+    /**
+     * The topic used for obtaining globally unique ids.
+     */
+    String VIRTUAL_NETWORK_TOPIC = "virtual-network-ids";
+
+    /**
+     * Returns a collection of all virtual networks created on behalf of the
+     * specified tenant.
+     *
+     * @param tenantId tenant identifier
+     * @return collection of networks
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId);
+
+    /**
+     * Returns the virtual network matching the network identifier.
+     *
+     * @param networkId virtual network identifier
+     * @return virtual network instance
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    VirtualNetwork getVirtualNetwork(NetworkId networkId);
+
+    /**
+     * Returns {@code tenantId} for specified virtual network id.
+     *
+     * @param networkId virtual network identifier
+     * @return tenantId tenant identifier
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    TenantId getTenantId(NetworkId networkId);
+
+    /**
+     * Returns a collection of all virtual devices in the specified network.
+     *
+     * @param networkId network identifier
+     * @return collection of devices
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    Set<VirtualDevice> getVirtualDevices(NetworkId networkId);
+
+    /**
+     * Returns a collection of all virtual hosts in the specified network.
+     *
+     * @param networkId network identifier
+     * @return collection of hosts
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    Set<VirtualHost> getVirtualHosts(NetworkId networkId);
+
+    /**
+     * Returns collection of all virtual links in the specified network.
+     *
+     * @param networkId network identifier
+     * @return collection of links
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    Set<VirtualLink> getVirtualLinks(NetworkId networkId);
+
+    /**
+     * Returns list of all virtual ports of the specified device. If the
+     * device identifier is null then all of the virtual ports in the specified
+     * network will be returned.
+     *
+     * @param networkId network identifier
+     * @param deviceId  device identifier
+     * @return list of ports
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    Set<VirtualPort> getVirtualPorts(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Returns list of physical device identifier mapping with the virtual
+     * device in the specified network. The physical devices are specified by
+     * port mapping mechanism.
+     *
+     * @param networkId network identifier
+     * @param deviceId the virtual device identifier
+     * @return collection of the specified device's identifier
+     */
+    Set<DeviceId> getPhysicalDevices(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Returns implementation of the specified service class for operating
+     * in the context of the given network.
+     * <p>
+     * The following services will be available:
+     * <ul>
+     * <li>{@link org.onosproject.net.device.DeviceService}</li>
+     * <li>{@link org.onosproject.net.link.LinkService}</li>
+     * <li>{@link org.onosproject.net.host.HostService}</li>
+     * <li>{@link org.onosproject.net.topology.TopologyService}</li>
+     * <li>{@link org.onosproject.net.topology.PathService}</li>
+     * <li>{@link org.onosproject.net.packet.PacketService}</li>
+     * <li>{@link org.onosproject.net.flow.FlowRuleService}</li>
+     * <li>{@link org.onosproject.net.flowobjective.FlowObjectiveService}</li>
+     * <li>{@link org.onosproject.net.intent.IntentService}</li>
+     * <li>{@link org.onosproject.mastership.MastershipService}</li>
+     * <li>{@link org.onosproject.mastership.MastershipAdminService}</li>
+     * <li>{@link org.onosproject.mastership.MastershipTermService}</li>
+     * </ul>
+     *
+     * @param networkId    network identifier
+     * @param serviceClass service class
+     * @param <T>          type of service
+     * @return implementation class
+     * @throws org.onlab.util.ItemNotFoundException    if no such network found
+     * @throws org.onlab.osgi.ServiceNotFoundException if no implementation found
+     */
+    <T> T get(NetworkId networkId, Class<T> serviceClass);
+
+    /**
+     * Returns service directory.
+     *
+     * @return a service directory
+     */
+    ServiceDirectory getServiceDirectory();
+
+    /**
+     * Returns the application identifier for a virtual network.
+     *
+     * @param networkId network identifier
+     * @return an representative application identifier for a virtual network
+     */
+    ApplicationId getVirtualNetworkApplicationId(NetworkId networkId);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStore.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStore.java
new file mode 100644
index 0000000..de74333
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStore.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TenantId;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.store.Store;
+
+import java.util.Set;
+
+/**
+ * Mechanism for distributing and storing virtual network model information.
+ */
+public interface VirtualNetworkStore
+        extends Store<VirtualNetworkEvent, VirtualNetworkStoreDelegate> {
+
+    /**
+     * Adds a new tenant ID to the store.
+     *
+     * @param tenantId tenant identifier
+     */
+    void addTenantId(TenantId tenantId);
+
+    /**
+     * Removes the specified tenant ID from the store.
+     *
+     * @param tenantId tenant identifier
+     */
+    void removeTenantId(TenantId tenantId);
+
+    /**
+     * Returns set of registered tenant IDs.
+     *
+     * @return set of tenant identifiers
+     */
+    Set<TenantId> getTenantIds();
+
+    /**
+     * Adds a new virtual network for the specified tenant to the store.
+     *
+     * @param tenantId tenant identifier
+     * @return the virtual network
+     */
+    VirtualNetwork addNetwork(TenantId tenantId);
+
+    /**
+     * Removes the specified virtual network from the store.
+     *
+     * @param networkId network identifier
+     */
+    void removeNetwork(NetworkId networkId);
+
+    /**
+     * Adds a new virtual device to the store. This device will have no ports.
+     *
+     * @param networkId network identifier
+     * @param deviceId  device identifier
+     * @return the virtual device
+     */
+    VirtualDevice addDevice(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Removes the specified virtual device from the given network.
+     *
+     * @param networkId network identifier
+     * @param deviceId  device identifier
+     */
+    void removeDevice(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Adds a new virtual host to the store.
+     *
+     * @param networkId network identifier
+     * @param hostId    host identifier
+     * @param mac       mac address
+     * @param vlan      vlan identifier
+     * @param location  host location
+     * @param ips       set of ip addresses
+     * @return the virtual host
+     */
+    VirtualHost addHost(NetworkId networkId, HostId hostId, MacAddress mac,
+                        VlanId vlan, HostLocation location, Set<IpAddress> ips);
+
+    /**
+     * Removes the specified virtual host from the store.
+     *
+     * @param networkId network identifier
+     * @param hostId    host identifier
+     */
+    void removeHost(NetworkId networkId, HostId hostId);
+
+    /**
+     * Adds a new virtual link.
+     *
+     * @param networkId  network identifier
+     * @param src        source end-point of the link
+     * @param dst        destination end-point of the link
+     * @param state      link state
+     * @param realizedBy underlying tunnel identifier using which this link is realized
+     * @return the virtual link
+     */
+    VirtualLink addLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst, Link.State state, TunnelId realizedBy);
+
+    /**
+     * Updates the tunnelId in the virtual link.
+     *
+     * @param virtualLink virtual link
+     * @param tunnelId    tunnel identifier
+     * @param state       link state
+     */
+    void updateLink(VirtualLink virtualLink, TunnelId tunnelId, Link.State state);
+
+    /**
+     * Removes the specified link from the store.
+     *
+     * @param networkId network identifier
+     * @param src       source connection point
+     * @param dst       destination connection point
+     * @return the virtual link
+     */
+    VirtualLink removeLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst);
+
+    /**
+     * Adds a new virtual port to the network.
+     *
+     * @param networkId  network identifier
+     * @param deviceId   device identifier
+     * @param portNumber port number
+     * @param realizedBy underlying port which realizes the virtual port
+     * @return the virtual port
+     */
+    VirtualPort addPort(NetworkId networkId, DeviceId deviceId,
+                        PortNumber portNumber, ConnectPoint realizedBy);
+
+    /**
+     * Binds an existing virtual port to the network.
+     *
+     * @param networkId  network identifier
+     * @param deviceId   device identifier
+     * @param portNumber port number
+     * @param realizedBy underlying port which realizes the virtual port
+     */
+     void bindPort(NetworkId networkId, DeviceId deviceId,
+                        PortNumber portNumber, ConnectPoint realizedBy);
+
+    /**
+     * Updates port state of an existing virtual port.
+     *
+     * @param networkId  network identifier
+     * @param deviceId   device identifier
+     * @param portNumber port number
+     * @param isEnabled  indicator whether the port is up and active
+     */
+     void updatePortState(NetworkId networkId, DeviceId deviceId,
+                        PortNumber portNumber, boolean isEnabled);
+
+    /**
+     * Removes the specified port from the given device and network.
+     *
+     * @param networkId  network identifier
+     * @param deviceId   device identifier
+     * @param portNumber port number
+     */
+    void removePort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber);
+
+    /**
+     * Returns the list of networks.
+     *
+     * @param tenantId tenant identifier
+     * @return set of virtual networks
+     */
+    Set<VirtualNetwork> getNetworks(TenantId tenantId);
+
+    /**
+     * Returns the virtual network for the given network identifier.
+     *
+     * @param networkId network identifier
+     * @return the virtual network
+     */
+    VirtualNetwork getNetwork(NetworkId networkId);
+
+    /**
+     * Returns the list of devices in the specified virtual network.
+     *
+     * @param networkId network identifier
+     * @return set of virtual devices
+     */
+    Set<VirtualDevice> getDevices(NetworkId networkId);
+
+    /**
+     * Returns the list of hosts in the specified virtual network.
+     *
+     * @param networkId network identifier
+     * @return set of virtual hosts
+     */
+    Set<VirtualHost> getHosts(NetworkId networkId);
+
+    /**
+     * Returns the list of virtual links in the specified virtual network.
+     *
+     * @param networkId network identifier
+     * @return set of virtual links
+     */
+    Set<VirtualLink> getLinks(NetworkId networkId);
+
+    /**
+     * Returns the virtual link matching the network identifier, source connect point,
+     * and destination connect point.
+     *
+     * @param networkId network identifier
+     * @param src       source connect point
+     * @param dst       destination connect point
+     * @return virtual link
+     */
+    VirtualLink getLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst);
+
+    /**
+     * Returns the list of ports of the specified virtual device.
+     *
+     * @param networkId network identifier
+     * @param deviceId  device identifier
+     * @return set of virtual networks
+     */
+    Set<VirtualPort> getPorts(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * Adds the intent to tunnel identifier mapping to the store.
+     *
+     * @param intent   intent
+     * @param tunnelId tunnel identifier
+     * @deprecated in Kingfisher Release (1.10)
+     */
+    @Deprecated
+    void addTunnelId(Intent intent, TunnelId tunnelId);
+
+    /**
+     * Return the set of tunnel identifiers store against the intent.
+     *
+     * @param intent intent
+     * @return set of tunnel identifiers
+     * @deprecated in Kingfisher Release (1.10)
+     */
+    @Deprecated
+    Set<TunnelId> getTunnelIds(Intent intent);
+
+    /**
+     * Removes the intent to tunnel identifier mapping from the store.
+     *
+     * @param intent   intent
+     * @param tunnelId tunnel identifier
+     * @deprecated in Kingfisher Release (1.10)
+     */
+    @Deprecated
+    void removeTunnelId(Intent intent, TunnelId tunnelId);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStoreDelegate.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStoreDelegate.java
new file mode 100644
index 0000000..202a0be
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStoreDelegate.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import org.onosproject.store.StoreDelegate;
+
+/**
+ * Network configuration store delegate abstraction.
+ */
+public interface VirtualNetworkStoreDelegate extends StoreDelegate<VirtualNetworkEvent> {
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPacketContext.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPacketContext.java
new file mode 100644
index 0000000..42b548a
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPacketContext.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import org.onosproject.net.packet.PacketContext;
+
+/**
+ * Represents context for processing an inbound packet for a virtual network,
+ * and (optionally) emitting a corresponding outbound packet.
+ */
+public interface VirtualPacketContext extends PacketContext {
+    /**
+     * Returns the network identifier.
+     *
+     * @return network id
+     */
+    NetworkId networkId();
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPort.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPort.java
new file mode 100644
index 0000000..a393e8e
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPort.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Port;
+
+/**
+ * Representation of a virtual port.
+ */
+@Beta
+public interface VirtualPort extends VirtualElement, Port {
+
+    /**
+     * Returns the underlying port using which this port is realized.
+     *
+     * @return underlying port which realizes this virtual port
+     */
+    ConnectPoint realizedBy();
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPortDescription.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPortDescription.java
new file mode 100644
index 0000000..0785641
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPortDescription.java
@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+import org.onosproject.net.device.PortDescription;
+
+/**
+ * Information about a virtual port.
+ */
+public interface VirtualPortDescription extends PortDescription {
+
+    // TODO: Add something about a requirement of virtual port.
+
+    /**
+     * Representation of the virtual port.
+     */
+    enum State {
+        /**
+         * Signifies that a virtual port is currently start.
+         */
+        START,
+
+        /**
+         * Signifies that a virtual port is currently stop.
+         */
+        STOP,
+
+        /**
+         * Signifies that a virtual port is pause for a moment.
+         */
+        PAUSE
+    }
+
+    /**
+     * Starts the virtual port.
+     */
+    void start();
+
+    /**
+     * Stops the virtual port.
+     */
+    void stop();
+
+    /**
+     * Pauses the virtual port for stopping a network or device.
+     * e.g. snapshot.
+     */
+    void pause();
+
+    /**
+     * Returns the virtual port state.
+     *
+     * @return state of virtual port
+     */
+    State state();
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualStore.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualStore.java
new file mode 100644
index 0000000..8a25874
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualStore.java
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+import org.onosproject.event.Event;
+import org.onosproject.store.StoreDelegate;
+
+/**
+ * Abstraction of a entity capable of storing and/or distributing information
+ * for virtual network across a cluster.
+ */
+public interface VirtualStore<E extends Event, D extends StoreDelegate<E>> {
+    /**
+     * Sets the delegate on the store.
+     *
+     * @param networkId a virtual network identifier
+     * @param delegate new store delegate
+     * @throws java.lang.IllegalStateException if a delegate is already
+     *                                         currently set on the store and is a different one that
+     */
+    void setDelegate(NetworkId networkId, D delegate);
+
+    /**
+     * Withdraws the delegate from the store.
+     *
+     * @param networkId a virtual network identifier
+     * @param delegate store delegate to withdraw
+     * @throws java.lang.IllegalArgumentException if the delegate is not
+     *                                            currently set on the store
+     */
+    void unsetDelegate(NetworkId networkId, D delegate);
+
+    /**
+     * Indicates whether the store has a delegate.
+     *
+     * @param networkId a virtual network identifier
+     * @return true if delegate is set
+     */
+    boolean hasDelegate(NetworkId networkId);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VnetService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VnetService.java
new file mode 100644
index 0000000..1889ad4
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/VnetService.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+/**
+ * Virtual network service interface.
+ */
+public interface VnetService {
+    NetworkId networkId();
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualDeviceCodec.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualDeviceCodec.java
new file mode 100644
index 0000000..c0c8cf8
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualDeviceCodec.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2018-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.codec;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.net.DeviceId;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * Codec for the VirtualDevice class.
+ */
+public class VirtualDeviceCodec extends JsonCodec<VirtualDevice> {
+
+    // JSON field names
+    private static final String ID = "deviceId";
+    private static final String NETWORK_ID = "networkId";
+
+    private static final String NULL_OBJECT_MSG = "VirtualDevice cannot be null";
+    private static final String MISSING_MEMBER_MSG = " member is required in VirtualDevice";
+
+    @Override
+    public ObjectNode encode(VirtualDevice vDev, CodecContext context) {
+        checkNotNull(vDev, NULL_OBJECT_MSG);
+
+        ObjectNode result = context.mapper().createObjectNode()
+                .put(NETWORK_ID, vDev.networkId().toString())
+                .put(ID, vDev.id().toString());
+
+        return result;
+    }
+
+    @Override
+    public VirtualDevice decode(ObjectNode json, CodecContext context) {
+        if (json == null || !json.isObject()) {
+            return null;
+        }
+
+        DeviceId dId = DeviceId.deviceId(extractMember(ID, json));
+        NetworkId nId = NetworkId.networkId(Long.parseLong(extractMember(NETWORK_ID, json)));
+        return new DefaultVirtualDevice(nId, dId);
+    }
+
+    /**
+     * Extract member from JSON ObjectNode.
+     *
+     * @param key key for which value is needed
+     * @param json JSON ObjectNode
+     * @return member value
+     */
+    private String extractMember(String key, ObjectNode json) {
+        return nullIsIllegal(json.get(key), key + MISSING_MEMBER_MSG).asText();
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualHostCodec.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualHostCodec.java
new file mode 100644
index 0000000..2ddb589
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualHostCodec.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2018-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.codec;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.incubator.net.virtual.DefaultVirtualHost;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * Codec for the VirtualHost class.
+ */
+public class VirtualHostCodec extends JsonCodec<VirtualHost> {
+
+    // JSON field names
+    static final String NETWORK_ID = "networkId";
+    static final String HOST_ID = "id";
+    static final String MAC_ADDRESS = "mac";
+    static final String VLAN = "vlan";
+    static final String IP_ADDRESSES = "ipAddresses";
+    static final String HOST_LOCATION = "locations";
+
+    private static final String NULL_OBJECT_MSG = "VirtualHost cannot be null";
+    private static final String MISSING_MEMBER_MSG = " member is required in VirtualHost";
+
+    @Override
+    public ObjectNode encode(VirtualHost vHost, CodecContext context) {
+        checkNotNull(vHost, NULL_OBJECT_MSG);
+
+        final JsonCodec<HostLocation> locationCodec =
+                context.codec(HostLocation.class);
+        final ObjectNode result = context.mapper().createObjectNode()
+                .put(NETWORK_ID, vHost.networkId().toString())
+                .put(HOST_ID, vHost.id().toString())
+                .put(MAC_ADDRESS, vHost.mac().toString())
+                .put(VLAN, vHost.vlan().toString());
+
+        final ArrayNode jsonIpAddresses = result.putArray(IP_ADDRESSES);
+        for (final IpAddress ipAddress : vHost.ipAddresses()) {
+            jsonIpAddresses.add(ipAddress.toString());
+        }
+        result.set(IP_ADDRESSES, jsonIpAddresses);
+
+        final ArrayNode jsonLocations = result.putArray("locations");
+        for (final HostLocation location : vHost.locations()) {
+            jsonLocations.add(locationCodec.encode(location, context));
+        }
+        result.set("locations", jsonLocations);
+
+        return result;
+    }
+
+    @Override
+    public VirtualHost decode(ObjectNode json, CodecContext context) {
+        if (json == null || !json.isObject()) {
+            return null;
+        }
+
+        NetworkId nId = NetworkId.networkId(Long.parseLong(extractMember(NETWORK_ID, json)));
+        MacAddress mac = MacAddress.valueOf(json.get("mac").asText());
+        VlanId vlanId = VlanId.vlanId((short) json.get("vlan").asInt(VlanId.UNTAGGED));
+
+        Set<HostLocation> locations = new HashSet<>();
+        JsonNode locationNodes = json.get("locations");
+        locationNodes.forEach(locationNode -> {
+            PortNumber portNumber = PortNumber.portNumber(locationNode.get("port").asText());
+            DeviceId deviceId = DeviceId.deviceId(locationNode.get("elementId").asText());
+            locations.add(new HostLocation(deviceId, portNumber, 0));
+        });
+
+        HostId id = HostId.hostId(mac, vlanId);
+
+        Iterator<JsonNode> ipStrings = json.get("ipAddresses").elements();
+        Set<IpAddress> ips = new HashSet<>();
+        while (ipStrings.hasNext()) {
+            ips.add(IpAddress.valueOf(ipStrings.next().asText()));
+        }
+
+        return new DefaultVirtualHost(nId, id, mac, vlanId, locations, ips);
+    }
+
+    /**
+     * Extract member from JSON ObjectNode.
+     *
+     * @param key key for which value is needed
+     * @param json JSON ObjectNode
+     * @return member value
+     */
+    private String extractMember(String key, ObjectNode json) {
+        return nullIsIllegal(json.get(key), key + MISSING_MEMBER_MSG).asText();
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualLinkCodec.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualLinkCodec.java
new file mode 100644
index 0000000..641982f
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualLinkCodec.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2018-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.codec;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.net.Link;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * Codec for the VirtualLink class.
+ */
+public class VirtualLinkCodec extends JsonCodec<VirtualLink> {
+
+    // JSON field names
+    private static final String NETWORK_ID = "networkId";
+
+    private static final String NULL_OBJECT_MSG = "VirtualLink cannot be null";
+    private static final String MISSING_MEMBER_MSG = " member is required in VirtualLink";
+
+    @Override
+    public ObjectNode encode(VirtualLink vLink, CodecContext context) {
+        checkNotNull(vLink, NULL_OBJECT_MSG);
+
+        ObjectNode result = context.mapper().createObjectNode()
+                .put(NETWORK_ID, vLink.networkId().toString());
+        JsonCodec<Link> codec = context.codec(Link.class);
+        ObjectNode linkResult = codec.encode(vLink, context);
+        result.setAll(linkResult);
+        return result;
+    }
+
+    @Override
+    public VirtualLink decode(ObjectNode json, CodecContext context) {
+        if (json == null || !json.isObject()) {
+            return null;
+        }
+        JsonCodec<Link> codec = context.codec(Link.class);
+        Link link = codec.decode(json, context);
+        NetworkId nId = NetworkId.networkId(Long.parseLong(extractMember(NETWORK_ID, json)));
+        return DefaultVirtualLink.builder()
+                .networkId(nId)
+                .src(link.src())
+                .dst(link.dst())
+                .build();
+    }
+
+    /**
+     * Extract member from JSON ObjectNode.
+     *
+     * @param key  key for which value is needed
+     * @param json JSON ObjectNode
+     * @return member value
+     */
+    private String extractMember(String key, ObjectNode json) {
+        return nullIsIllegal(json.get(key), key + MISSING_MEMBER_MSG).asText();
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualNetworkCodec.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualNetworkCodec.java
new file mode 100644
index 0000000..32945e4
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualNetworkCodec.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2018-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.codec;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * Codec for the VirtualNetwork class.
+ */
+public class VirtualNetworkCodec extends JsonCodec<VirtualNetwork> {
+
+    // JSON field names
+    private static final String NETWORK_ID = "networkId";
+    private static final String TENANT_ID = "tenantId";
+
+    private static final String NULL_OBJECT_MSG = "VirtualNetwork cannot be null";
+    private static final String MISSING_MEMBER_MSG = " member is required in VirtualNetwork";
+
+    @Override
+    public ObjectNode encode(VirtualNetwork vnet, CodecContext context) {
+        checkNotNull(vnet, NULL_OBJECT_MSG);
+
+        ObjectNode result = context.mapper().createObjectNode()
+                .put(NETWORK_ID, vnet.id().toString())
+                .put(TENANT_ID, vnet.tenantId().toString());
+
+        return result;
+    }
+
+    @Override
+    public VirtualNetwork decode(ObjectNode json, CodecContext context) {
+        if (json == null || !json.isObject()) {
+            return null;
+        }
+
+        NetworkId nId = NetworkId.networkId(Long.parseLong(extractMember(NETWORK_ID, json)));
+        TenantId tId = TenantId.tenantId(extractMember(TENANT_ID, json));
+        return new DefaultVirtualNetwork(nId, tId);
+    }
+
+    private String extractMember(String key, ObjectNode json) {
+        return nullIsIllegal(json.get(key), key + MISSING_MEMBER_MSG).asText();
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualPortCodec.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualPortCodec.java
new file mode 100644
index 0000000..474196e
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/VirtualPortCodec.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2018-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.codec;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * Codec for the VirtualPort class.
+ */
+public class VirtualPortCodec extends JsonCodec<VirtualPort> {
+
+    // JSON field names
+    private static final String NETWORK_ID = "networkId";
+    private static final String DEVICE_ID = "deviceId";
+    private static final String PORT_NUM = "portNum";
+    private static final String PHYS_DEVICE_ID = "physDeviceId";
+    private static final String PHYS_PORT_NUM = "physPortNum";
+
+    private static final String NULL_OBJECT_MSG = "VirtualPort cannot be null";
+    private static final String MISSING_MEMBER_MSG = " member is required in VirtualPort";
+    private static final String INVALID_VIRTUAL_DEVICE = " is not a valid VirtualDevice";
+
+    @Override
+    public ObjectNode encode(VirtualPort vPort, CodecContext context) {
+        checkNotNull(vPort, NULL_OBJECT_MSG);
+
+        ObjectNode result = context.mapper().createObjectNode()
+                .put(NETWORK_ID, vPort.networkId().toString())
+                .put(DEVICE_ID, vPort.element().id().toString())
+                .put(PORT_NUM, vPort.number().toString())
+                .put(PHYS_DEVICE_ID, vPort.realizedBy().deviceId().toString())
+                .put(PHYS_PORT_NUM, vPort.realizedBy().port().toString());
+
+        return result;
+    }
+
+    @Override
+    public VirtualPort decode(ObjectNode json, CodecContext context) {
+        if (json == null || !json.isObject()) {
+            return null;
+        }
+
+        NetworkId nId = NetworkId.networkId(Long.parseLong(extractMember(NETWORK_ID, json)));
+        DeviceId dId = DeviceId.deviceId(extractMember(DEVICE_ID, json));
+
+        VirtualNetworkService vnetService = context.getService(VirtualNetworkService.class);
+        Set<VirtualDevice> vDevs = vnetService.getVirtualDevices(nId);
+        VirtualDevice vDev = vDevs.stream()
+                .filter(virtualDevice -> virtualDevice.id().equals(dId))
+                .findFirst().orElse(null);
+        nullIsIllegal(vDev, dId.toString() + INVALID_VIRTUAL_DEVICE);
+
+        PortNumber portNum = PortNumber.portNumber(extractMember(PORT_NUM, json));
+        DeviceId physDId = DeviceId.deviceId(extractMember(PHYS_DEVICE_ID, json));
+        PortNumber physPortNum = PortNumber.portNumber(extractMember(PHYS_PORT_NUM, json));
+
+        ConnectPoint realizedBy = new ConnectPoint(physDId, physPortNum);
+        return new DefaultVirtualPort(nId, vDev, portNum, realizedBy);
+    }
+
+    private String extractMember(String key, ObjectNode json) {
+        return nullIsIllegal(json.get(key), key + MISSING_MEMBER_MSG).asText();
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/package-info.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/package-info.java
new file mode 100644
index 0000000..8999592
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/codec/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2018-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.
+ */
+
+/**
+ * Network virtualization data model codecs.
+ */
+package org.onosproject.incubator.net.virtual.codec;
\ No newline at end of file
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/AbstractVirtualListenerManager.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/AbstractVirtualListenerManager.java
new file mode 100644
index 0000000..57dfe0c
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/AbstractVirtualListenerManager.java
@@ -0,0 +1,91 @@
+/*
+ * 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.event;
+
+import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.event.Event;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.event.EventListener;
+import org.onosproject.event.ListenerRegistry;
+import org.onosproject.event.ListenerService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VnetService;
+
+/**
+ * Basis for virtual event components which need to export listener mechanism.
+ */
+public abstract class AbstractVirtualListenerManager
+        <E extends Event, L extends EventListener<E>>
+        implements ListenerService<E, L>, VnetService {
+
+    protected final NetworkId networkId;
+    protected final VirtualNetworkService manager;
+    protected final ServiceDirectory serviceDirectory;
+
+    protected EventDeliveryService eventDispatcher;
+
+    private ListenerRegistry<E, L> listenerRegistry;
+
+    private VirtualListenerRegistryManager listenerManager =
+            VirtualListenerRegistryManager.getInstance();
+
+    public AbstractVirtualListenerManager(VirtualNetworkService manager,
+                                          NetworkId networkId,
+                                          Class<? extends Event> eventClass) {
+        this.manager = manager;
+        this.networkId = networkId;
+        this.serviceDirectory = manager.getServiceDirectory();
+
+        //Set default event delivery service by default
+        this.eventDispatcher = serviceDirectory.get(EventDeliveryService.class);
+
+        //Initialize and reference to the listener registry
+        this.listenerRegistry = listenerManager.getRegistry(networkId, eventClass);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void addListener(L listener) {
+        listenerRegistry.addListener(listener);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void removeListener(L listener) {
+        listenerRegistry.removeListener(listener);
+    }
+
+    /**
+     * Safely posts the specified event to the local event dispatcher.
+     * If there is no event dispatcher or if the event is null, this method
+     * is a noop.
+     *
+     * @param event event to be posted; may be null
+     */
+    protected void post(E event) {
+        if (event != null && eventDispatcher != null) {
+            VirtualEvent<E> vEvent =
+                    new VirtualEvent<E>(networkId, VirtualEvent.Type.POSTED, event);
+            eventDispatcher.post(vEvent);
+        }
+    }
+
+    @Override
+    public NetworkId networkId() {
+        return this.networkId;
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/VirtualEvent.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/VirtualEvent.java
new file mode 100644
index 0000000..bbba983
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/VirtualEvent.java
@@ -0,0 +1,54 @@
+/*
+ * 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.event;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.event.Event;
+import org.onosproject.incubator.net.virtual.NetworkId;
+
+/**
+ * Base class for virtual network event that encapsulates a normal event.
+ */
+public class VirtualEvent<E extends Event>
+        extends AbstractEvent<VirtualEvent.Type, E> {
+
+    private NetworkId networkId;
+
+    /**
+     * Type of virtual network events.
+     */
+    public enum Type {
+        /**
+         * A new virtual event has been posted.
+         */
+        POSTED
+    }
+
+    protected VirtualEvent(NetworkId networkId, Type type, E subject) {
+        super(type, subject);
+        this.networkId = networkId;
+    }
+
+    protected VirtualEvent(NetworkId networkId, Type type, E subject, long time) {
+        super(type, subject, time);
+        this.networkId = networkId;
+    }
+
+    public NetworkId networkId() {
+        return networkId;
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/VirtualListenerRegistryManager.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/VirtualListenerRegistryManager.java
new file mode 100644
index 0000000..55210dd
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/VirtualListenerRegistryManager.java
@@ -0,0 +1,99 @@
+/*
+ * 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.event;
+
+import com.google.common.collect.Maps;
+import org.onosproject.event.Event;
+import org.onosproject.event.EventSink;
+import org.onosproject.event.ListenerRegistry;
+import org.onosproject.incubator.net.virtual.NetworkId;
+
+import java.util.Map;
+
+/**
+ * Base implementation of an virtual event sink and a registry capable of tracking
+ * listeners and dispatching events to them as part of event sink processing.
+ */
+public final class VirtualListenerRegistryManager
+        implements EventSink<VirtualEvent> {
+
+    private Map<NetworkId, Map<Class<? extends Event>, ListenerRegistry>>
+            listenerMapByNetwork = Maps.newConcurrentMap();
+
+    ListenerRegistry lastStart;
+
+    // non-instantiable (except for our Singleton)
+    private VirtualListenerRegistryManager() {
+
+    }
+
+    public static VirtualListenerRegistryManager getInstance() {
+        return SingletonHelper.INSTANCE;
+    }
+
+    public ListenerRegistry getRegistry(NetworkId networkId,
+                                        Class<? extends Event> eventClass) {
+        Map<Class<? extends Event>, ListenerRegistry> listenerMapByEvent =
+                listenerMapByNetwork.get(networkId);
+
+        if (listenerMapByEvent == null) {
+            listenerMapByEvent = Maps.newConcurrentMap();
+            listenerMapByNetwork.putIfAbsent(networkId, listenerMapByEvent);
+        }
+
+        ListenerRegistry listenerRegistry = listenerMapByEvent.get(eventClass);
+
+        if (listenerRegistry == null) {
+            listenerRegistry = new ListenerRegistry();
+            listenerMapByEvent.putIfAbsent(eventClass, listenerRegistry);
+        }
+
+        return listenerRegistry;
+    }
+
+    @Override
+    public void process(VirtualEvent event) {
+        NetworkId networkId = event.networkId();
+        Event originalEvent = (Event) event.subject();
+
+        ListenerRegistry listenerRegistry =
+                listenerMapByNetwork.get(networkId).get(originalEvent.getClass());
+        if (listenerRegistry != null) {
+            listenerRegistry.process(originalEvent);
+            lastStart = listenerRegistry;
+        }
+    }
+
+    @Override
+    public void onProcessLimit() {
+        lastStart.onProcessLimit();
+    }
+
+    /**
+     * Prevents object instantiation from external.
+     */
+    private static final class SingletonHelper {
+        private static final String ILLEGAL_ACCESS_MSG =
+                "Should not instantiate this class.";
+        private static final VirtualListenerRegistryManager INSTANCE =
+                new VirtualListenerRegistryManager();
+
+        private SingletonHelper() {
+            throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
+        }
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/package-info.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/package-info.java
new file mode 100644
index 0000000..448df90
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/event/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Virtual network event delivery subsystem interfaces &amp; supporting abstractions.
+ */
+package org.onosproject.incubator.net.virtual.event;
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/intent/VirtualIntentCompiler.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/intent/VirtualIntentCompiler.java
new file mode 100644
index 0000000..e76bf6e
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/intent/VirtualIntentCompiler.java
@@ -0,0 +1,43 @@
+/*
+ * 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.intent;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.intent.Intent;
+
+import java.util.List;
+
+/**
+ * Abstraction of a compiler which is capable of taking an intent
+ * and translating it to other, potentially installable, intents for virtual networks.
+ *
+ * @param <T> the type of intent
+ */
+@Beta
+public interface VirtualIntentCompiler<T extends Intent> {
+    /**
+     * Compiles the specified intent into other intents.
+     *
+     * @param networkId   network identifier
+     * @param intent      intent to be compiled
+     * @param installable previous compilation result; optional
+     * @return list of resulting intents
+     * @throws VirtualIntentException if issues are encountered while compiling the intent
+     */
+     List<Intent> compile(NetworkId networkId, T intent, List<Intent> installable);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/intent/VirtualIntentException.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/intent/VirtualIntentException.java
new file mode 100644
index 0000000..49cb908
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/intent/VirtualIntentException.java
@@ -0,0 +1,48 @@
+/*
+ * 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.intent;
+
+public class VirtualIntentException extends RuntimeException {
+
+    //FIXME: how to obatin UID?
+    private static final long serialVersionUID = 1907263634145241319L;
+
+    /**
+     * Constructs an exception with no message and no underlying cause.
+     */
+    public VirtualIntentException() {
+    }
+
+    /**
+     * Constructs an exception with the specified message.
+     *
+     * @param message the message describing the specific nature of the error
+     */
+    public VirtualIntentException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs an exception with the specified message and the underlying cause.
+     *
+     * @param message the message describing the specific nature of the error
+     * @param cause   the underlying cause of this error
+     */
+    public VirtualIntentException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/intent/package-info.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/intent/package-info.java
new file mode 100644
index 0000000..c5673ac
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/intent/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+/**
+ * Set of abstractions for conveying high-level intents for treatment of
+ * selected network traffic by allowing applications to express the
+ * <em>what</em> rather than the <em>how</em> for virtual networks.
+ */
+package org.onosproject.incubator.net.virtual.intent;
\ No newline at end of file
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/package-info.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/package-info.java
new file mode 100644
index 0000000..d9ced32
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Network virtualization data models and services.
+ */
+package org.onosproject.incubator.net.virtual;
\ No newline at end of file
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProvider.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProvider.java
new file mode 100644
index 0000000..bb4ba30
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProvider.java
@@ -0,0 +1,37 @@
+/*
+ * 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.provider;
+
+import org.onosproject.net.provider.ProviderId;
+
+public abstract class AbstractVirtualProvider implements VirtualProvider {
+    private final ProviderId providerId;
+
+    /**
+     * Creates a virtual provider with the supplied identifier.
+     *
+     * @param id a virtual provider id
+     */
+    protected AbstractVirtualProvider(ProviderId id) {
+        this.providerId = id;
+    }
+
+    @Override
+    public ProviderId id() {
+        return providerId;
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProviderService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProviderService.java
new file mode 100644
index 0000000..2411e26
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProviderService.java
@@ -0,0 +1,62 @@
+/*
+ * 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.provider;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Base implementation of a virtual provider service,
+ * which tracks the provider to which it is issued and can be invalidated.
+ *
+ * @param <P> type of the information provider
+ */
+public abstract class AbstractVirtualProviderService<P extends VirtualProvider>
+        implements VirtualProviderService<P> {
+
+    private boolean isValid = true;
+    private P provider = null;
+
+    /**
+     * Creates a virtual provider service on behalf of the specified provider.
+     *
+     * @param provider provider to which this service is being issued
+     */
+    protected void setProvider(P provider) {
+        this.provider = provider;
+    }
+
+    /**
+     * Invalidates this provider service.
+     */
+    public void invalidate() {
+        isValid = false;
+    }
+
+    /**
+     * Checks the validity of this provider service.
+     *
+     * @throws java.lang.IllegalStateException if the service is no longer valid
+     */
+    public void checkValidity() {
+        checkState(isValid, "Provider service is no longer valid");
+    }
+
+    @Override
+    public P provider() {
+        return provider;
+    }
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/InternalRoutingAlgorithm.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/InternalRoutingAlgorithm.java
new file mode 100644
index 0000000..c17f0d9
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/InternalRoutingAlgorithm.java
@@ -0,0 +1,36 @@
+/*
+ * 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.provider;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Path;
+
+/**
+ * Abstraction of an embedding algorithm used for embedding virtual objects
+ * into the underlying physical network.
+ */
+public interface InternalRoutingAlgorithm {
+    /**
+     * Find a route between two connect points (i.e. ports)
+     * according to the own logic.
+     *
+     * @param src A start point
+     * @param dst A sink point
+     * @return The path between src and dst calculated from the algorithm
+     */
+    Path findPath(ConnectPoint src, ConnectPoint dst);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualDeviceProvider.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualDeviceProvider.java
new file mode 100644
index 0000000..9191eaf
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualDeviceProvider.java
@@ -0,0 +1,66 @@
+/*
+ * 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.provider;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.PortNumber;
+
+/**
+ * Abstraction of a virtual device information provider.
+ */
+public interface VirtualDeviceProvider extends VirtualProvider {
+
+    /**
+     * Notifies the provider of a mastership role change for the specified
+     * device as decided by the core.
+     *
+     * @param deviceId  device identifier
+     * @param newRole newly determined mastership role
+     */
+    void roleChanged(DeviceId deviceId, MastershipRole newRole);
+
+    /**
+     * Indicates whether or not the specified connect points on the underlying
+     * network are traversable.
+     *
+     * @param src source connection point
+     * @param dst destination connection point
+     * @return true if the destination is reachable from the source
+     */
+    boolean isTraversable(ConnectPoint src, ConnectPoint dst);
+
+    /**
+     * Indicates whether or not the all physical devices mapped by the given
+     * virtual device are reachable.
+     *
+     * @param deviceId  device identifier
+     * @return true if the all physical devices are reachable, false otherwise
+     */
+    boolean isReachable(DeviceId deviceId);
+
+    /**
+     * Administratively enables or disables a port.
+     *
+     * @param deviceId device identifier
+     * @param portNumber port number
+     * @param enable true if port is to be enabled, false to disable
+     */
+    void changePortState(DeviceId deviceId, PortNumber portNumber,
+                         boolean enable);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualDeviceProviderService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualDeviceProviderService.java
new file mode 100644
index 0000000..e2d584c
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualDeviceProviderService.java
@@ -0,0 +1,69 @@
+/*
+ * 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.provider;
+
+import org.onosproject.incubator.net.virtual.VirtualPortDescription;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.device.PortStatistics;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Service through which virtual device providers can inject virtual device
+ * information into the core.
+ */
+public interface VirtualDeviceProviderService
+        extends VirtualProviderService<VirtualDeviceProvider> {
+
+    /**
+     * Updates information about all ports of a device. It is up to the core to
+     * determine what has changed.
+     *
+     * @param deviceId         identity of the device
+     * @param portDescs list of virtual device ports
+     */
+    void updatePorts(DeviceId deviceId, List<VirtualPortDescription> portDescs);
+
+    /**
+     * Notifies the core about port status change of a single port.
+     *
+     * @param deviceId        identity of the device
+     * @param portDesc description of the virtual port that changed
+     */
+    void portStatusChanged(DeviceId deviceId, VirtualPortDescription portDesc);
+
+    /**
+     * Notifies the core about the result of a RoleRequest sent to a device.
+     *
+     * @param deviceId identity of the device
+     * @param requested mastership role that was requested by the node
+     * @param response mastership role the switch accepted
+     */
+    void receivedRoleReply(DeviceId deviceId, MastershipRole requested,
+                           MastershipRole response);
+
+    /**
+     * Updates statistics about all ports of a device.
+     *
+     * @param deviceId          identity of the device
+     * @param portStatistics  list of device port statistics
+     */
+    void updatePortStatistics(DeviceId deviceId,
+                              Collection<PortStatistics> portStatistics);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProvider.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProvider.java
new file mode 100644
index 0000000..8a4ec34
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProvider.java
@@ -0,0 +1,55 @@
+/*
+ * 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.provider;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+
+/**
+ * Abstraction of a virtual flow rule provider.
+ * This provider virtualizes and de-virtualizes FlowRule.
+ * See {@link org.onosproject.net.flow.FlowRule}.
+ */
+public interface VirtualFlowRuleProvider extends VirtualProvider {
+
+    /**
+     * Instructs the provider to apply the specified flow rules to their
+     * respective virtual devices.
+     *
+     * @param networkId the identity of the virtual network where this rule applies
+     * @param flowRules one or more flow rules
+     */
+    void applyFlowRule(NetworkId networkId, FlowRule... flowRules);
+
+    /**
+     * Instructs the provider to remove the specified flow rules to their
+     * respective virtual devices.
+     *
+     * @param networkId the identity of the virtual network where this rule applies
+     * @param flowRules one or more flow rules
+     */
+    void removeFlowRule(NetworkId networkId, FlowRule... flowRules);
+
+    /**
+     * Installs a batch of flow rules. Each flowrule is associated to an
+     * operation which results in either addition, removal or modification.
+     *
+     * @param networkId the identity of the virtual network where this rule applies
+     * @param batch a batch of flow rules
+     */
+    void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProviderService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProviderService.java
new file mode 100644
index 0000000..065af9c
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProviderService.java
@@ -0,0 +1,75 @@
+/*
+ * 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.provider;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.CompletedBatchOperation;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.TableStatisticsEntry;
+
+import java.util.List;
+
+/**
+ * Service through which virtual flow rule providers can inject information into
+ * the core.
+ */
+public interface VirtualFlowRuleProviderService
+        extends VirtualProviderService<VirtualFlowRuleProvider> {
+
+    /**
+     * Signals that a flow rule that was previously installed has been removed.
+     *
+     * @param flowEntry removed flow entry
+     */
+    void flowRemoved(FlowEntry flowEntry);
+
+    /**
+     * Pushes the collection of flow entries currently applied on the given
+     * virtual device.
+     *
+     * @param deviceId device identifier
+     * @param flowEntries collection of flow rules
+     */
+    void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries);
+
+    /**
+     * Pushes the collection of flow entries currently applied on the given
+     * device without flowMissing process.
+     *
+     * @param deviceId device identifier
+     * @param flowEntries collection of flow rules
+     */
+    void pushFlowMetricsWithoutFlowMissing(DeviceId deviceId, Iterable<FlowEntry> flowEntries);
+
+    /**
+     * Pushes the collection of table statistics entries currently extracted
+     * from the given virtual device.
+     *
+     * @param deviceId device identifier
+     * @param tableStatsEntries collection of flow table statistics entries
+     */
+    void pushTableStatistics(DeviceId deviceId, List<TableStatisticsEntry> tableStatsEntries);
+
+    /**
+     * Indicates to the core that the requested batch operation has
+     * been completed.
+     *
+     * @param batchId the batch which was processed
+     * @param operation the resulting outcome of the operation
+     */
+    void batchOperationCompleted(long batchId, CompletedBatchOperation operation);
+
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualGroupProvider.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualGroupProvider.java
new file mode 100644
index 0000000..72d68c3
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualGroupProvider.java
@@ -0,0 +1,39 @@
+/*
+ * 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.provider;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.group.GroupOperations;
+
+/**
+ * Abstraction of group provider for virtual network.
+ */
+public interface VirtualGroupProvider extends VirtualProvider {
+    /**
+     * Performs a batch of group operation in the specified virtual device
+     * with the specified parameters.
+     *
+     * @param networkId the identity of the virtual network where this rule applies
+     * @param deviceId device identifier on which the batch of group
+     * operations to be executed
+     * @param groupOps immutable list of group operation
+     */
+    void performGroupOperation(NetworkId networkId, DeviceId deviceId,
+                               GroupOperations groupOps);
+
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualGroupProviderService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualGroupProviderService.java
new file mode 100644
index 0000000..0fdaca8
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualGroupProviderService.java
@@ -0,0 +1,54 @@
+/*
+ * 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.provider;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupOperation;
+
+import java.util.Collection;
+
+/**
+ * Service through which Group providers can inject information into
+ * the virtual network core.
+ */
+public interface VirtualGroupProviderService
+        extends VirtualProviderService<VirtualGroupProvider> {
+    /**
+     * Notifies core if any failure from data plane during group operations.
+     *
+     * @param deviceId the device ID
+     * @param operation offended group operation
+     */
+    void groupOperationFailed(DeviceId deviceId, GroupOperation operation);
+
+    /**
+     * Pushes the collection of group detected in the data plane along
+     * with statistics.
+     *
+     * @param deviceId device identifier
+     * @param groupEntries collection of group entries as seen in data plane
+     */
+    void pushGroupMetrics(DeviceId deviceId, Collection<Group> groupEntries);
+
+    /**
+     * Notifies store of group failovers.
+     *
+     * @param failoverGroups failover groups in which a failover has occurred
+     */
+    void notifyOfFailovers(Collection<Group> failoverGroups);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualMeterProvider.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualMeterProvider.java
new file mode 100644
index 0000000..6ac80e4
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualMeterProvider.java
@@ -0,0 +1,52 @@
+/*
+ * 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.provider;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.MeterOperation;
+import org.onosproject.net.meter.MeterOperations;
+
+/**
+ * Abstraction of a Meter provider for virtual network.
+ */
+public interface VirtualMeterProvider extends VirtualProvider {
+    /**
+     * Performs a batch of meter operation on the specified virtual device
+     * with the specified parameters.
+     *
+     * @param networkId the identity of the virtual network where this rule applies
+     * @param deviceId device identifier on which the batch of group
+     * operations to be executed
+     * @param meterOps immutable list of meter operation
+     */
+    void performMeterOperation(NetworkId networkId, DeviceId deviceId,
+                               MeterOperations meterOps);
+
+
+    /**
+     * Performs a meter operation on the specified vitual device with the
+     * specified parameters.
+     *
+     * @param networkId the identity of the virtual network where this rule applies
+     * @param deviceId device identifier on which the batch of group
+     * operations to be executed
+     * @param meterOp a meter operation
+     */
+    void performMeterOperation(NetworkId networkId, DeviceId deviceId,
+                               MeterOperation meterOp);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualMeterProviderService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualMeterProviderService.java
new file mode 100644
index 0000000..46e4a7d
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualMeterProviderService.java
@@ -0,0 +1,66 @@
+/*
+ * 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.provider;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterFailReason;
+import org.onosproject.net.meter.MeterFeatures;
+import org.onosproject.net.meter.MeterOperation;
+
+import java.util.Collection;
+
+/**
+ * Service through which meter providers can inject information
+ * into the virtual network subsystem core.
+ */
+public interface VirtualMeterProviderService
+        extends VirtualProviderService<VirtualMeterProvider> {
+    /**
+     * Notifies the core that a meter operation failed for a
+     * specific reason.
+     *
+     * @param operation the failed operation
+     * @param reason the failure reason
+     */
+    void meterOperationFailed(MeterOperation operation, MeterFailReason reason);
+
+    /**
+     * Pushes the collection of meters observed on the data plane as
+     * well as their associated statistics.
+     *
+     * @param deviceId a device id
+     * @param meterEntries a collection of meter entries
+     */
+    void pushMeterMetrics(DeviceId deviceId, Collection<Meter> meterEntries);
+
+    /**
+     * Pushes the meter features collected from the device.
+     *
+     * @param deviceId the device Id
+     * @param meterfeatures the meter features
+     */
+    void pushMeterFeatures(DeviceId deviceId,
+                           MeterFeatures meterfeatures);
+
+    /**
+     * Delete meter features collected from the device.
+     *
+     * @param deviceId the device id
+     */
+    void deleteMeterFeatures(DeviceId deviceId);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProvider.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProvider.java
new file mode 100644
index 0000000..038d4b3
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProvider.java
@@ -0,0 +1,38 @@
+/*
+ * 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.provider;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.provider.Provider;
+
+/**
+ * Entity capable of providing traffic isolation constructs for use in
+ * implementation of virtual devices and virtual links.
+ */
+public interface VirtualNetworkProvider extends Provider {
+
+    /**
+     * Indicates whether or not the specified connect points on the underlying
+     * network are traversable/reachable.
+     *
+     * @param src source connection point
+     * @param dst destination connection point
+     * @return true if the destination is reachable from the source
+     */
+    boolean isTraversable(ConnectPoint src, ConnectPoint dst);
+
+    // TODO: Further enhance this interface to support the virtual intent programming across this boundary.
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderRegistry.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderRegistry.java
new file mode 100644
index 0000000..6fbb1a7
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderRegistry.java
@@ -0,0 +1,25 @@
+/*
+ * 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.provider;
+
+import org.onosproject.net.provider.ProviderRegistry;
+
+/**
+ * Abstraction of a virtual network provider registry.
+ */
+public interface VirtualNetworkProviderRegistry
+        extends ProviderRegistry<VirtualNetworkProvider, VirtualNetworkProviderService> {
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderService.java
new file mode 100644
index 0000000..ee7d9a6
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderService.java
@@ -0,0 +1,64 @@
+/*
+ * 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.provider;
+
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.provider.ProviderService;
+
+import java.util.Set;
+
+/**
+ * Service through which virtual network providers can inject information into
+ * the core.
+ */
+public interface VirtualNetworkProviderService extends ProviderService<VirtualNetworkProvider> {
+
+    /**
+     * Set of separate topology clusters expressed in terms of connect points which
+     * belong to the same SCC of the underlying topology.
+     *
+     * @param clusters set of sets of mutually reachable connection points;
+     *                 the outer sets are not mutually reachable
+     */
+    void topologyChanged(Set<Set<ConnectPoint>> clusters);
+
+    // TBD: Is the above sufficient to determine health/viability of virtual entities based on
+    // clustering (SCC) of the physical ones?
+
+    /**
+     * This method is used to notify the VirtualNetwork service that a tunnel is now ACTIVE.
+     *
+     * @param networkId network identifier
+     * @param src       source connection point
+     * @param dst       destination connection point
+     * @param tunnelId  tunnel identifier
+     */
+    void tunnelUp(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId);
+
+    /**
+     * This method is used to notify the VirtualNetwork service that a tunnel is now
+     * FAILED or INACTIVE.
+     *
+     * @param networkId network identifier
+     * @param src       source connection point
+     * @param dst       destination connection point
+     * @param tunnelId  tunnel identifier
+     */
+    void tunnelDown(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId);
+
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualPacketProvider.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualPacketProvider.java
new file mode 100644
index 0000000..4cc8d80
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualPacketProvider.java
@@ -0,0 +1,35 @@
+/*
+ * 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.provider;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.packet.OutboundPacket;
+
+/**
+ * Abstraction of a virtual packet provider capable of emitting packets
+ * from virtual network core services to the underlay network.
+ * This provider de-virtualizes and virtualize PacketContext.
+ */
+public interface VirtualPacketProvider extends VirtualProvider {
+    /**
+     * Emits the specified outbound packet onto the underlay physical network.
+     * This provider maps the requested packets for physical network.
+     *
+     * @param networkId the virtual network ID
+     * @param packet outbound packet in the context of virtual network
+     */
+    void emit(NetworkId networkId, OutboundPacket packet);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualPacketProviderService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualPacketProviderService.java
new file mode 100644
index 0000000..3c2b4c2
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualPacketProviderService.java
@@ -0,0 +1,35 @@
+/*
+ * 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.provider;
+
+import org.onosproject.net.packet.PacketContext;
+
+/**
+ * Entity capable of processing inbound packets for virtual networks.
+ */
+public interface VirtualPacketProviderService
+        extends VirtualProviderService<VirtualPacketProvider> {
+
+    /**
+     * Submits inbound packet context for processing to virtual network core.
+     * This processing will be done synchronously, i.e. run-to-completion.
+     * This context is translated with virtual concepts.
+     *
+     * @param context inbound packet context
+     */
+    void processPacket(PacketContext context);
+
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProvider.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProvider.java
new file mode 100644
index 0000000..ac0dfb6
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProvider.java
@@ -0,0 +1,34 @@
+/*
+ * 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.provider;
+
+import org.onosproject.net.provider.ProviderId;
+
+/**
+ * Abstraction of a provider of information about virtual network environment.
+ * The role of virtual providers is to translate virtual objects into physical
+ * objects, vice versa.
+ */
+public interface VirtualProvider {
+
+    /**
+     * Returns the provider identifier.
+     *
+     * @return provider identification
+     */
+    ProviderId id();
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProviderRegistryService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProviderRegistryService.java
new file mode 100644
index 0000000..546463c
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProviderRegistryService.java
@@ -0,0 +1,122 @@
+/*
+ * 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.provider;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Set;
+
+/**
+ * Registry for tracking information providers with the core.
+ */
+public interface VirtualProviderRegistryService {
+
+    /**
+     * Registers the supplied virtual provider.
+     *
+     * @param virtualProvider a virtual provider to be registered
+     * @throws java.lang.IllegalArgumentException if the provider is registered already
+     */
+    void registerProvider(VirtualProvider virtualProvider);
+
+    /**
+     * Unregisters the supplied virtual provider.
+     * As a result the previously issued virtual provider service will be invalidated
+     * and any subsequent invocations of its methods may throw
+     * {@link java.lang.IllegalStateException}.
+     * <p>
+     * Unregistering a virtual provider that has not been previously registered results
+     * in a no-op.
+     * </p>
+     *
+     * @param virtualProvider a virtual provider to be unregistered
+     */
+    void unregisterProvider(VirtualProvider virtualProvider);
+
+    /**
+     * Registers the supplied virtual provider.
+     *
+     * @param networkId a virtual network identifier
+     * @param virtualProviderService a virtual provider service to be registered
+     */
+    void registerProviderService(NetworkId networkId,
+                                 VirtualProviderService virtualProviderService);
+
+    /**
+     * Unregisters the supplied virtual provider service.
+     *
+     * @param networkId a virtual network identifier
+     * @param virtualProviderService a virtual provider service to be unregistered
+     */
+    void unregisterProviderService(NetworkId networkId,
+                                   VirtualProviderService virtualProviderService);
+
+    /**
+     * Returns a set of currently registered virtual provider identities.
+     *
+     * @return set of virtual provider identifiers
+     */
+    Set<ProviderId> getProviders();
+
+    /**
+     * Returns a set of currently registered virtual provider identities
+     * corresponding to the requested providerService.
+     *
+     * @param virtualProviderService a virtual provider service
+     * @return set of virtual provider identifiers
+     */
+    Set<ProviderId> getProvidersByService(VirtualProviderService virtualProviderService);
+
+    /**
+     * Returns the virtual provider registered with the specified provider ID or null
+     * if none is found for the given provider family and default fall-back is
+     * not supported.
+     *
+     * @param providerId provider identifier
+     * @return provider
+     */
+    VirtualProvider getProvider(ProviderId providerId);
+
+    /**
+     * Returns the virtual provider for the specified device ID based on URI scheme.
+     *
+     * @param deviceId virtual device identifier
+     * @return provider bound to the URI scheme
+     */
+    VirtualProvider getProvider(DeviceId deviceId);
+
+    /**
+     * Returns the virtual provider registered with the specified scheme.
+     *
+     * @param scheme provider scheme
+     * @return provider
+     */
+    VirtualProvider getProvider(String scheme);
+
+    /**
+     * Returns a virtual provider service corresponding to
+     * the virtual network and provider class type.
+     *
+     * @param networkId a virtual network identifier
+     * @param providerClass a type of virtual provider
+     * @return a virtual provider service
+     */
+    VirtualProviderService getProviderService(NetworkId networkId,
+                                              Class<? extends VirtualProvider> providerClass);
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProviderService.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProviderService.java
new file mode 100644
index 0000000..8ad378f
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualProviderService.java
@@ -0,0 +1,33 @@
+/*
+ * 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.provider;
+
+/**
+ * Abstraction of a service through which virtual providers can inject information
+ * about the network environment into the virtual core.
+ *
+ * @param <P> type of the information virtual provider
+ */
+
+public interface VirtualProviderService<P extends VirtualProvider> {
+    /**
+     * Returns the virtual provider to which this service has been issued.
+     *
+     * @return virtual provider to which this service has been assigned
+     */
+    P provider();
+}
diff --git a/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/package-info.java b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/package-info.java
new file mode 100644
index 0000000..8d360d5
--- /dev/null
+++ b/apps/virtual/api/src/main/java/org/onosproject/incubator/net/virtual/provider/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Network virtualization provider interfaces and implementation.
+ */
+package org.onosproject.incubator.net.virtual.provider;
\ No newline at end of file
diff --git a/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/ComparatorsTest.java b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/ComparatorsTest.java
new file mode 100644
index 0000000..ba208bf
--- /dev/null
+++ b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/ComparatorsTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2018-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;
+
+import org.junit.Test;
+import org.onlab.packet.ChassisId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TenantId;
+import org.onosproject.net.provider.ProviderId;
+
+import static org.junit.Assert.*;
+import static org.onosproject.incubator.net.virtual.Comparators.VIRTUAL_DEVICE_COMPARATOR;
+import static org.onosproject.incubator.net.virtual.Comparators.VIRTUAL_NETWORK_COMPARATOR;
+import static org.onosproject.incubator.net.virtual.Comparators.VIRTUAL_PORT_COMPARATOR;
+import static org.onosproject.net.DeviceId.deviceId;
+
+public class ComparatorsTest {
+    private static final ProviderId PID = new ProviderId("of", "foo");
+    private static final DeviceId DID = deviceId("of:foo");
+    private static final String MFR = "whitebox";
+    private static final String HW = "1.1.x";
+    private static final String SW = "3.9.1";
+    private static final String SN = "43311-12345";
+    private static final ChassisId CID = new ChassisId();
+
+    @Test
+    public void testVirtualNetworkComparator() {
+        assertNotEquals(0, VIRTUAL_NETWORK_COMPARATOR.compare(network(10, "tenantID"), network(10, "tenantID1")));
+        assertNotEquals(0, VIRTUAL_NETWORK_COMPARATOR.compare(network(10, "tenantID"), network(15, "tenantID1")));
+        assertNotEquals(0, VIRTUAL_NETWORK_COMPARATOR.compare(network(15, "tenantID1"), network(10, "tenantID1")));
+        assertNotEquals(0, VIRTUAL_NETWORK_COMPARATOR.compare(network(15, "tenantID"), network(10, "tenantID1")));
+    }
+
+    private VirtualNetwork network(int networkID, String tenantID) {
+        return new DefaultVirtualNetwork(NetworkId.networkId(networkID), TenantId.tenantId(tenantID));
+    }
+
+    @Test
+    public void testVirtualDeviceComparator() {
+        assertEquals(0, VIRTUAL_DEVICE_COMPARATOR.compare(vd(0, "of:foo"), vd(0, "of:foo")));
+        assertEquals(0, VIRTUAL_DEVICE_COMPARATOR.compare(vd(3, "of:foo"), vd(0, "of:foo")));
+        assertNotEquals(0, VIRTUAL_DEVICE_COMPARATOR.compare(vd(0, "of:bar"), vd(0, "of:foo")));
+        assertNotEquals(0, VIRTUAL_DEVICE_COMPARATOR.compare(vd(3, "of:bar"), vd(0, "of:foo")));
+    }
+
+    private VirtualDevice vd(int netID, String devID) {
+        return new DefaultVirtualDevice(NetworkId.networkId(netID), DeviceId.deviceId(devID));
+    }
+
+    @Test
+    public void testVirtualPortComparator() {
+        assertEquals(0, VIRTUAL_PORT_COMPARATOR.compare(vPort(2), vPort(2)));
+        assertEquals(4, VIRTUAL_PORT_COMPARATOR.compare(vPort(900), vPort(5)));
+        assertEquals(-8, VIRTUAL_PORT_COMPARATOR.compare(vPort(0), vPort(8)));
+    }
+
+    private VirtualPort vPort(int portNumber) {
+        return new DefaultVirtualPort(NetworkId.networkId(20),
+                                      new DefaultDevice(PID, DID, null, MFR, HW, SW, SN, CID),
+                                      PortNumber.portNumber(portNumber),
+                                      new ConnectPoint(DID, PortNumber.portNumber(900)));
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualDeviceTest.java b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualDeviceTest.java
new file mode 100644
index 0000000..22be664
--- /dev/null
+++ b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualDeviceTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onosproject.net.TestDeviceParams;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Test of the default virtual device model entity.
+ */
+public class DefaultVirtualDeviceTest extends TestDeviceParams {
+
+    /**
+     * Checks that the DefaultVirtualDevice class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultVirtualDevice.class);
+    }
+
+    @Test
+    public void testEquality() {
+        DefaultVirtualDevice device1 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID1);
+        DefaultVirtualDevice device2 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID1);
+        DefaultVirtualDevice device3 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID2);
+        DefaultVirtualDevice device4 =
+                new DefaultVirtualDevice(NetworkId.networkId(1), DID1);
+
+        new EqualsTester().addEqualityGroup(device1, device2).addEqualityGroup(device3)
+                .addEqualityGroup(device4).testEquals();
+    }
+}
diff --git a/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualHostTest.java b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualHostTest.java
new file mode 100644
index 0000000..7fcf70d
--- /dev/null
+++ b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualHostTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onosproject.net.TestDeviceParams;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Test of the default virtual host model entity.
+ */
+public class DefaultVirtualHostTest extends TestDeviceParams {
+
+    /**
+     * Checks that the DefaultVirtualHost class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultVirtualHost.class);
+    }
+
+    /**
+     * Tests the DefaultVirtualHost equality method.
+     */
+    @Test
+    public void testEquality() {
+        DefaultVirtualHost host1 =
+                new DefaultVirtualHost(NetworkId.networkId(0), HID1, MAC1, VLAN1, LOC1, IPSET1);
+        DefaultVirtualHost host2 =
+                new DefaultVirtualHost(NetworkId.networkId(0), HID1, MAC1, VLAN1, LOC1, IPSET1);
+        DefaultVirtualHost host3 =
+                new DefaultVirtualHost(NetworkId.networkId(0), HID2, MAC1, VLAN1, LOC1, IPSET1);
+        DefaultVirtualHost host4 =
+                new DefaultVirtualHost(NetworkId.networkId(1), HID2, MAC1, VLAN1, LOC1, IPSET1);
+
+        new EqualsTester().addEqualityGroup(host1, host2).addEqualityGroup(host3)
+                .addEqualityGroup(host4).testEquals();
+    }
+}
diff --git a/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualLinkTest.java b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualLinkTest.java
new file mode 100644
index 0000000..b96290f
--- /dev/null
+++ b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualLinkTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Test of the default virtual link model entity.
+ */
+public class DefaultVirtualLinkTest extends TestDeviceParams {
+
+    /**
+     * Checks that the DefaultVirtualLink class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultVirtualLink.class);
+    }
+
+    /**
+     * Tests the DefaultVirtualLink Builder to ensure that the src cannot be null.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testBuilderNullSrc() {
+        DefaultVirtualDevice device1 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID1);
+        DefaultVirtualDevice device2 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID2);
+        ConnectPoint src = new ConnectPoint(device1.id(), PortNumber.portNumber(1));
+        ConnectPoint dst = new ConnectPoint(device2.id(), PortNumber.portNumber(2));
+
+        DefaultVirtualLink.builder()
+                .src(null)
+                .build();
+    }
+
+    /**
+     * Tests the DefaultVirtualLink Builder to ensure that the dst cannot be null.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testBuilderNullDst() {
+        DefaultVirtualDevice device1 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID1);
+        DefaultVirtualDevice device2 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID2);
+        ConnectPoint src = new ConnectPoint(device1.id(), PortNumber.portNumber(1));
+        ConnectPoint dst = new ConnectPoint(device2.id(), PortNumber.portNumber(2));
+
+        DefaultVirtualLink.builder()
+                .dst(null)
+                .build();
+    }
+
+    /**
+     * Tests the DefaultVirtualLink Builder to ensure that the networkId cannot be null.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testBuilderNullNetworkId() {
+        DefaultVirtualDevice device1 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID1);
+        DefaultVirtualDevice device2 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID2);
+        ConnectPoint src = new ConnectPoint(device1.id(), PortNumber.portNumber(1));
+        ConnectPoint dst = new ConnectPoint(device2.id(), PortNumber.portNumber(2));
+
+        DefaultVirtualLink.builder()
+                .networkId(null)
+                .build();
+    }
+
+    /**
+     * Tests the DefaultVirtualLink equality method.
+     */
+    @Test
+    public void testEquality() {
+        DefaultVirtualDevice device1 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID1);
+        DefaultVirtualDevice device2 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID2);
+        ConnectPoint src = new ConnectPoint(device1.id(), PortNumber.portNumber(1));
+        ConnectPoint dst = new ConnectPoint(device2.id(), PortNumber.portNumber(2));
+
+        VirtualLink link1 = DefaultVirtualLink.builder()
+                .networkId(NetworkId.networkId(0))
+                .src(src)
+                .dst(dst)
+                .tunnelId(TunnelId.valueOf("1"))
+                .build();
+        VirtualLink link2 = DefaultVirtualLink.builder()
+                .networkId(NetworkId.networkId(0))
+                .src(src)
+                .dst(dst)
+                .tunnelId(TunnelId.valueOf("1"))
+                .build();
+        VirtualLink link3 = DefaultVirtualLink.builder()
+                .networkId(NetworkId.networkId(0))
+                .src(src)
+                .dst(dst)
+                .tunnelId(TunnelId.valueOf("2"))
+                .build();
+        VirtualLink link4 = DefaultVirtualLink.builder()
+                .networkId(NetworkId.networkId(1))
+                .src(src)
+                .dst(dst)
+                .tunnelId(TunnelId.valueOf("3"))
+                .build();
+
+        new EqualsTester().addEqualityGroup(link1, link2).addEqualityGroup(link3)
+                .addEqualityGroup(link4).testEquals();
+    }
+}
diff --git a/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetworkTest.java b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetworkTest.java
new file mode 100644
index 0000000..7ff4715
--- /dev/null
+++ b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetworkTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onosproject.net.TenantId;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Test of the default virtual network model entity.
+ */
+public class DefaultVirtualNetworkTest {
+    final String tenantIdValue1 = "TENANT_ID1";
+    final String tenantIdValue2 = "TENANT_ID2";
+
+    /**
+     * Checks that the DefaultVirtualNetwork class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultVirtualNetwork.class);
+    }
+
+    @Test
+    public void testEquality() {
+        DefaultVirtualNetwork network1 =
+                new DefaultVirtualNetwork(NetworkId.networkId(0), TenantId.tenantId(tenantIdValue1));
+        DefaultVirtualNetwork network2 =
+                new DefaultVirtualNetwork(NetworkId.networkId(0), TenantId.tenantId(tenantIdValue1));
+        DefaultVirtualNetwork network3 =
+                new DefaultVirtualNetwork(NetworkId.networkId(0), TenantId.tenantId(tenantIdValue2));
+        DefaultVirtualNetwork network4 =
+                new DefaultVirtualNetwork(NetworkId.networkId(1), TenantId.tenantId(tenantIdValue2));
+
+        new EqualsTester().addEqualityGroup(network1, network2).addEqualityGroup(network3)
+                .addEqualityGroup(network4).testEquals();
+    }
+}
diff --git a/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualPortTest.java b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualPortTest.java
new file mode 100644
index 0000000..61ba611
--- /dev/null
+++ b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualPortTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Test of the default virtual port model entity.
+ */
+public class DefaultVirtualPortTest extends TestDeviceParams {
+    /**
+     * Checks that the DefaultVirtualPort class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultVirtualPort.class);
+    }
+
+    @Test
+    public void testEquality() {
+        DefaultVirtualDevice device1 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID1);
+        DefaultVirtualDevice device2 =
+                new DefaultVirtualDevice(NetworkId.networkId(0), DID2);
+
+        ConnectPoint cpA = new ConnectPoint(device1.id(), PortNumber.portNumber(1));
+        ConnectPoint cpB = new ConnectPoint(device1.id(), PortNumber.portNumber(2));
+        ConnectPoint cpC = new ConnectPoint(device2.id(), PortNumber.portNumber(2));
+
+        DefaultVirtualPort port1 =
+                new DefaultVirtualPort(NetworkId.networkId(0), device1,
+                                       PortNumber.portNumber(1), cpA);
+        DefaultVirtualPort port2 =
+                new DefaultVirtualPort(NetworkId.networkId(0), device1,
+                                       PortNumber.portNumber(1), cpA);
+        DefaultVirtualPort port3 =
+                new DefaultVirtualPort(NetworkId.networkId(0), device1,
+                                       PortNumber.portNumber(2), cpB);
+        DefaultVirtualPort port4 =
+                new DefaultVirtualPort(NetworkId.networkId(1), device2,
+                                       PortNumber.portNumber(2), cpC);
+
+
+        new EqualsTester().addEqualityGroup(port1, port2).addEqualityGroup(port3)
+                .addEqualityGroup(port4).testEquals();
+    }
+}
diff --git a/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/codec/VirtualHostCodecTest.java b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/codec/VirtualHostCodecTest.java
new file mode 100644
index 0000000..043e434
--- /dev/null
+++ b/apps/virtual/api/src/test/java/org/onosproject/incubator/net/virtual/codec/VirtualHostCodecTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2018-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.codec;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Set;
+import java.util.stream.IntStream;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.codec.impl.MockCodecContext;
+import org.onosproject.incubator.net.virtual.DefaultVirtualHost;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualHost;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.NetTestTools;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableSet;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isOneOf;
+import static org.hamcrest.Matchers.notNullValue;
+
+/**
+ * Tests VirtualHostCodec class.
+ */
+@Ignore
+public class VirtualHostCodecTest {
+
+    private static final String TEST_IP1 = "1.1.1.1";
+    private static final String TEST_IP2 = "2.2.2.2";
+    private static final String TEST_HOST_ID = "12:34:56:78:90:11/1";
+    private static final String TEST_MAC_ADDRESS = "11:11:22:22:33:33";
+    private static final long TEST_NETWORK_ID = 44L;
+    private static final short TEST_VLAN_ID = (short) 12;
+    private static final ConnectPoint CONNECT_POINT =
+            NetTestTools.connectPoint("d1", 1);
+
+    @Test
+    public void testEncode() {
+        MockCodecContext context = new MockCodecContext();
+        NetworkId networkId = NetworkId.networkId(TEST_NETWORK_ID);
+        HostId id = NetTestTools.hid(TEST_HOST_ID);
+        MacAddress mac = MacAddress.valueOf(TEST_MAC_ADDRESS);
+        VlanId vlan = VlanId.vlanId(TEST_VLAN_ID);
+        HostLocation location =
+                new HostLocation(CONNECT_POINT, 0L);
+        Set<IpAddress> ips = ImmutableSet.of(IpAddress.valueOf(TEST_IP1),
+                                             IpAddress.valueOf(TEST_IP2));
+        VirtualHost host =
+                new DefaultVirtualHost(networkId, id, mac, vlan, location, ips);
+        JsonCodec<VirtualHost> codec = context.codec(VirtualHost.class);
+        ObjectNode node = codec.encode(host, context);
+
+        assertThat(node.get(VirtualHostCodec.NETWORK_ID).asLong(),
+                   is(TEST_NETWORK_ID));
+        assertThat(node.get(VirtualHostCodec.HOST_ID).asText(),
+                   is(TEST_HOST_ID));
+        assertThat(node.get(VirtualHostCodec.MAC_ADDRESS).asText(),
+                   is(TEST_MAC_ADDRESS));
+        assertThat(node.get(VirtualHostCodec.VLAN).asInt(),
+                   is((int) TEST_VLAN_ID));
+        assertThat(node.get(VirtualHostCodec.HOST_LOCATION).get(0).get("elementId").asText(),
+                   is(location.deviceId().toString()));
+        assertThat(node.get(VirtualHostCodec.HOST_LOCATION).get(0).get("port").asLong(),
+                   is(location.port().toLong()));
+
+        JsonNode jsonIps = node.get(VirtualHostCodec.IP_ADDRESSES);
+        assertThat(jsonIps, notNullValue());
+        assertThat(jsonIps.isArray(), is(true));
+        assertThat(jsonIps.size(), is(ips.size()));
+
+        IntStream.of(0, 1).forEach(index ->
+            assertThat(jsonIps.get(index).asText(),
+                       isOneOf(TEST_IP1, TEST_IP2)));
+    }
+
+    @Test
+    public void testDecode() throws IOException {
+        MockCodecContext context = new MockCodecContext();
+        InputStream jsonStream =
+                VirtualHostCodecTest.class.getResourceAsStream("VirtualHost.json");
+        JsonNode json = context.mapper().readTree(jsonStream);
+        assertThat(json, notNullValue());
+        JsonCodec<VirtualHost> codec = context.codec(VirtualHost.class);
+        VirtualHost virtualHost = codec.decode((ObjectNode) json, context);
+        assertThat(virtualHost, notNullValue());
+
+        assertThat(virtualHost.networkId().id(),
+                   is(TEST_NETWORK_ID));
+        assertThat(virtualHost.id().toString(),
+                   is(NetTestTools.hid(TEST_MAC_ADDRESS + "/12").toString()));
+        assertThat(virtualHost.mac().toString(),
+                   is(TEST_MAC_ADDRESS));
+        assertThat(virtualHost.vlan().id(),
+                   is((short) TEST_VLAN_ID));
+        assertThat(virtualHost.location().deviceId(),
+                   is(CONNECT_POINT.deviceId()));
+        assertThat(virtualHost.location().port().toLong(),
+                   is(CONNECT_POINT.port().toLong()));
+
+
+        assertThat(virtualHost.ipAddresses().contains(IpAddress.valueOf(TEST_IP1)),
+                   is(true));
+        assertThat(virtualHost.ipAddresses().contains(IpAddress.valueOf(TEST_IP2)),
+                   is(true));
+    }
+}
diff --git a/apps/virtual/api/src/test/resources/org/onosproject/incubator/net/virtual/codec/VirtualHost.json b/apps/virtual/api/src/test/resources/org/onosproject/incubator/net/virtual/codec/VirtualHost.json
new file mode 100644
index 0000000..818ce0b
--- /dev/null
+++ b/apps/virtual/api/src/test/resources/org/onosproject/incubator/net/virtual/codec/VirtualHost.json
@@ -0,0 +1,15 @@
+{
+  "networkId": "44",
+  "mac": "11:11:22:22:33:33",
+  "vlan": "12",
+  "ipAddresses": [
+    "1.1.1.1",
+    "2.2.2.2"
+  ],
+  "locations": [
+    {
+      "elementId": "of:d1",
+      "port": "1"
+    }
+  ]
+}
diff --git a/apps/virtual/app/BUILD b/apps/virtual/app/BUILD
new file mode 100644
index 0000000..15941f8
--- /dev/null
+++ b/apps/virtual/app/BUILD
@@ -0,0 +1,26 @@
+COMPILE_DEPS = CORE_DEPS + JACKSON + REST + CLI + [
+    "@metrics_core//jar",
+    "//core/common:onos-core-common",
+    "//core/net:onos-core-net",
+    "//core/store/serializers:onos-core-serializers",
+    "//apps/tunnel/api:onos-apps-tunnel-api",
+    "//apps/virtual/api:onos-apps-virtual-api",
+]
+
+TEST_DEPS = TEST_ADAPTERS + [
+    "@minimal_json//jar",
+    "@jersey_client//jar",
+    "//web/api:onos-rest-tests",
+    "//utils/osgi:onlab-osgi-tests",
+]
+
+osgi_jar_with_tests(
+    api_description = "REST API for Virtual Networks",
+    api_package = "org.onosproject.incubator.net.virtual.rest",
+    api_title = "Virtual Networks",
+    api_version = "1.0",
+    karaf_command_packages = ["org.onosproject.incubator.net.virtual.cli"],
+    test_deps = TEST_DEPS,
+    visibility = ["//visibility:public"],
+    deps = COMPILE_DEPS,
+)
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantAddCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantAddCommand.java
new file mode 100644
index 0000000..a449afb
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantAddCommand.java
@@ -0,0 +1,45 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+
+/**
+ * Creates a new virtual network tenant.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-add-tenant",
+        description = "Creates a new virtual network tenant.")
+
+public class TenantAddCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "id", description = "Tenant ID",
+            required = true, multiValued = false)
+    String id = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        service.registerTenantId(TenantId.tenantId(id));
+        print("Tenant successfully added.");
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantCompleter.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantCompleter.java
new file mode 100644
index 0000000..29a625c
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantCompleter.java
@@ -0,0 +1,53 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+
+import java.util.List;
+import java.util.SortedSet;
+
+/**
+ * Tenant Id completer.
+ */
+@Service
+public class TenantCompleter implements Completer {
+    @Override
+    public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+        // Delegate string completer
+        StringsCompleter delegate = new StringsCompleter();
+
+        // Fetch our service and feed it's offerings to the string completer
+        VirtualNetworkAdminService service = AbstractShellCommand.get(VirtualNetworkAdminService.class);
+
+        SortedSet<String> strings = delegate.getStrings();
+
+        for (TenantId tenantId : service.getTenantIds()) {
+            strings.add(tenantId.id());
+        }
+
+        // Now let the completer do the work for figuring out what to offer.
+        return delegate.complete(session, commandLine, candidates);
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantListCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantListCommand.java
new file mode 100644
index 0000000..6590090
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantListCommand.java
@@ -0,0 +1,53 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.utils.Comparators;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Lists all tenants.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-tenants",
+        description = "Lists all virtual network tenants.")
+public class TenantListCommand extends AbstractShellCommand {
+
+    private static final String FMT_TENANT = "tenantId=%s";
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        List<TenantId> tenants = new ArrayList<>();
+        tenants.addAll(service.getTenantIds());
+        Collections.sort(tenants, Comparators.TENANT_ID_COMPARATOR);
+
+        tenants.forEach(this::printTenant);
+    }
+
+    private void printTenant(TenantId tenantId) {
+        print(FMT_TENANT, tenantId.id());
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantRemoveCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantRemoveCommand.java
new file mode 100644
index 0000000..2877f59
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/TenantRemoveCommand.java
@@ -0,0 +1,47 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+
+/**
+ * Creates a new virtual network tenant.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-remove-tenant",
+        description = "Removes a virtual network tenant.")
+
+public class TenantRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "id", description = "Tenant ID",
+            required = true, multiValued = false)
+    @Completion(TenantCompleter.class)
+    String id = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        service.unregisterTenantId(TenantId.tenantId(id));
+        print("Tenant successfully removed.");
+    }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceCompleter.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceCompleter.java
new file mode 100644
index 0000000..410b483
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceCompleter.java
@@ -0,0 +1,70 @@
+/*
+ * 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.cli;
+
+import static org.onlab.osgi.DefaultServiceDirectory.getService;
+
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractChoicesCompleter;
+import org.onosproject.incubator.net.virtual.Comparators;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Virtual device completer.
+ *
+ * Assumes the first argument which can be parsed to a number is network id.
+ */
+@Service
+public class VirtualDeviceCompleter extends AbstractChoicesCompleter {
+    @Override
+    protected List<String> choices() {
+        //parse argument list for network id
+        String[] argsArray = commandLine.getArguments();
+        for (String str : argsArray) {
+            if (str.matches("[0-9]+")) {
+                long networkId = Long.valueOf(str);
+                return getSortedVirtualDevices(networkId).stream()
+                        .map(virtualDevice -> virtualDevice.id().toString())
+                        .collect(Collectors.toList());
+            }
+        }
+        return Collections.singletonList("Missing network id");
+    }
+
+    /**
+     * Returns the list of virtual devices sorted using the network identifier.
+     *
+     * @param networkId network id
+     * @return sorted virtual device list
+     */
+    private List<VirtualDevice> getSortedVirtualDevices(long networkId) {
+        VirtualNetworkService service = getService(VirtualNetworkService.class);
+
+        List<VirtualDevice> virtualDevices = new ArrayList<>();
+        virtualDevices.addAll(service.getVirtualDevices(NetworkId.networkId(networkId)));
+        Collections.sort(virtualDevices, Comparators.VIRTUAL_DEVICE_COMPARATOR);
+        return virtualDevices;
+    }
+
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceCreateCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceCreateCommand.java
new file mode 100644
index 0000000..187c0e1
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceCreateCommand.java
@@ -0,0 +1,51 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.net.DeviceId;
+
+/**
+ * Creates a new virtual device.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-create-device",
+        description = "Creates a new virtual device in a network.")
+public class VirtualDeviceCreateCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "deviceId", description = "Device ID",
+            required = true, multiValued = false)
+    String deviceId = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        service.createVirtualDevice(NetworkId.networkId(networkId), DeviceId.deviceId(deviceId));
+        print("Virtual device successfully created.");
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceListCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceListCommand.java
new file mode 100644
index 0000000..4a4acfc
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceListCommand.java
@@ -0,0 +1,77 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.Comparators;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Lists all virtual devices for the network ID.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-devices",
+        description = "Lists all virtual devices in a virtual network.")
+public class VirtualDeviceListCommand extends AbstractShellCommand {
+
+    private static final String FMT_VIRTUAL_DEVICE =
+            "deviceId=%s";
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Override
+    protected void doExecute() {
+
+        getSortedVirtualDevices().forEach(this::printVirtualDevice);
+    }
+
+    /**
+     * Returns the list of virtual devices sorted using the device identifier.
+     *
+     * @return sorted virtual device list
+     */
+    private List<VirtualDevice> getSortedVirtualDevices() {
+        VirtualNetworkService service = get(VirtualNetworkService.class);
+
+        List<VirtualDevice> virtualDevices = new ArrayList<>();
+        virtualDevices.addAll(service.getVirtualDevices(NetworkId.networkId(networkId)));
+        Collections.sort(virtualDevices, Comparators.VIRTUAL_DEVICE_COMPARATOR);
+        return virtualDevices;
+    }
+
+    /**
+     * Prints out each virtual device.
+     *
+     * @param virtualDevice virtual device
+     */
+    private void printVirtualDevice(VirtualDevice virtualDevice) {
+        print(FMT_VIRTUAL_DEVICE, virtualDevice.id());
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceRemoveCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceRemoveCommand.java
new file mode 100644
index 0000000..f6213c7
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualDeviceRemoveCommand.java
@@ -0,0 +1,53 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cli.net.DeviceIdCompleter;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.net.DeviceId;
+
+/**
+ * Removes a virtual device.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-remove-device",
+        description = "Removes a virtual device.")
+public class VirtualDeviceRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "deviceId", description = "Device ID",
+            required = true, multiValued = false)
+    @Completion(DeviceIdCompleter.class)
+    String deviceId = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        service.removeVirtualDevice(NetworkId.networkId(networkId), DeviceId.deviceId(deviceId));
+        print("Virtual device successfully removed.");
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualFlowsListCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualFlowsListCommand.java
new file mode 100644
index 0000000..05da804
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualFlowsListCommand.java
@@ -0,0 +1,283 @@
+/*
+ * 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.cli;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.action.Option;
+import org.onlab.util.StringFilter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cli.PlaceholderCompleter;
+import org.onosproject.cli.net.FlowRuleStatusCompleter;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowEntry.FlowEntryState;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.utils.Comparators;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+
+/**
+ * Lists all currently-known flows.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-flows",
+         description = "Lists all currently-known flows for a virtual network.")
+public class VirtualFlowsListCommand extends AbstractShellCommand {
+
+    private static final Predicate<FlowEntry> TRUE_PREDICATE = f -> true;
+
+    public static final String ANY = "any";
+
+    private static final String LONG_FORMAT = "    id=%s, state=%s, bytes=%s, "
+            + "packets=%s, duration=%s, liveType=%s, priority=%s, tableId=%s, appId=%s, "
+            + "payLoad=%s, selector=%s, treatment=%s";
+
+    private static final String SHORT_FORMAT = "    %s, bytes=%s, packets=%s, "
+            + "table=%s, priority=%s, selector=%s, treatment=%s";
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "state", description = "Flow Rule state",
+            required = false, multiValued = false)
+    @Completion(FlowRuleStatusCompleter.class)
+    String state = null;
+
+    @Argument(index = 2, name = "uri", description = "Device ID",
+              required = false, multiValued = false)
+    @Completion(VirtualDeviceCompleter.class)
+    String uri = null;
+
+    @Argument(index = 3, name = "table", description = "Table ID",
+            required = false, multiValued = false)
+    @Completion(PlaceholderCompleter.class)
+    String table = null;
+
+    @Option(name = "-s", aliases = "--short",
+            description = "Print more succinct output for each flow",
+            required = false, multiValued = false)
+    private boolean shortOutput = false;
+
+    @Option(name = "-c", aliases = "--count",
+            description = "Print flow count only",
+            required = false, multiValued = false)
+    private boolean countOnly = false;
+
+    @Option(name = "-f", aliases = "--filter",
+            description = "Filter flows by specific key",
+            required = false, multiValued = true)
+    private List<String> filter = new ArrayList<>();
+
+    private Predicate<FlowEntry> predicate = TRUE_PREDICATE;
+
+    private StringFilter contentFilter;
+
+    @Override
+    protected void doExecute() {
+        CoreService coreService = get(CoreService.class);
+
+        VirtualNetworkService vnetservice = get(VirtualNetworkService.class);
+        DeviceService deviceService = vnetservice.get(NetworkId.networkId(networkId),
+                                                      DeviceService.class);
+        FlowRuleService service = vnetservice.get(NetworkId.networkId(networkId),
+                                                  FlowRuleService.class);
+        contentFilter = new StringFilter(filter, StringFilter.Strategy.AND);
+
+        compilePredicate();
+
+        SortedMap<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service);
+
+        if (outputJson()) {
+            print("%s", json(flows.keySet(), flows));
+        } else {
+            flows.forEach((device, flow) -> printFlows(device, flow, coreService));
+        }
+    }
+
+    /**
+     * Produces a JSON array of flows grouped by the each device.
+     *
+     * @param devices     collection of devices to group flow by
+     * @param flows       collection of flows per each device
+     * @return JSON array
+     */
+    private JsonNode json(Iterable<Device> devices,
+                          Map<Device, List<FlowEntry>> flows) {
+        ObjectMapper mapper = new ObjectMapper();
+        ArrayNode result = mapper.createArrayNode();
+        for (Device device : devices) {
+            result.add(json(mapper, device, flows.get(device)));
+        }
+        return result;
+    }
+
+    /**
+     * Compiles a predicate to find matching flows based on the command
+     * arguments.
+     */
+    private void compilePredicate() {
+        if (state != null && !state.equals(ANY)) {
+            final FlowEntryState feState = FlowEntryState.valueOf(state.toUpperCase());
+            predicate = predicate.and(f -> f.state().equals(feState));
+        }
+
+        if (table != null) {
+            final int tableId = Integer.parseInt(table);
+            predicate = predicate.and(f -> f.tableId() == tableId);
+        }
+    }
+
+    // Produces JSON object with the flows of the given device.
+    private ObjectNode json(ObjectMapper mapper,
+                            Device device, List<FlowEntry> flows) {
+        ObjectNode result = mapper.createObjectNode();
+        ArrayNode array = mapper.createArrayNode();
+
+        flows.forEach(flow -> array.add(jsonForEntity(flow, FlowEntry.class)));
+
+        result.put("device", device.id().toString())
+                .put("flowCount", flows.size())
+                .set("flows", array);
+        return result;
+    }
+
+    /**
+     * Returns the list of devices sorted using the device ID URIs.
+     *
+     * @param deviceService device service
+     * @param service flow rule service
+     * @return sorted device list
+     */
+    protected SortedMap<Device, List<FlowEntry>> getSortedFlows(DeviceService deviceService,
+                                                          FlowRuleService service) {
+        SortedMap<Device, List<FlowEntry>> flows = new TreeMap<>(Comparators.ELEMENT_COMPARATOR);
+        List<FlowEntry> rules;
+
+        Iterable<Device> devices = null;
+        if (uri == null) {
+            devices = deviceService.getDevices();
+        } else {
+            Device dev = deviceService.getDevice(DeviceId.deviceId(uri));
+            devices = (dev == null) ? deviceService.getDevices()
+                                    : Collections.singletonList(dev);
+        }
+
+        for (Device d : devices) {
+            if (predicate.equals(TRUE_PREDICATE)) {
+                rules = newArrayList(service.getFlowEntries(d.id()));
+            } else {
+                rules = newArrayList();
+                for (FlowEntry f : service.getFlowEntries(d.id())) {
+                    if (predicate.test(f)) {
+                        rules.add(f);
+                    }
+                }
+            }
+            rules.sort(Comparators.FLOW_RULE_COMPARATOR);
+
+            flows.put(d, rules);
+        }
+        return flows;
+    }
+
+    /**
+     * Prints flows.
+     *
+     * @param d     the device
+     * @param flows the set of flows for that device
+     * @param coreService core system service
+     */
+    protected void printFlows(Device d, List<FlowEntry> flows,
+                              CoreService coreService) {
+        List<FlowEntry> filteredFlows = flows.stream().
+                filter(f -> contentFilter.filter(f)).collect(Collectors.toList());
+        boolean empty = filteredFlows == null || filteredFlows.isEmpty();
+        print("deviceId=%s, flowRuleCount=%d", d.id(), empty ? 0 : filteredFlows.size());
+        if (empty || countOnly) {
+            return;
+        }
+
+        for (FlowEntry f : filteredFlows) {
+            if (shortOutput) {
+                print(SHORT_FORMAT, f.state(), f.bytes(), f.packets(),
+                        f.tableId(), f.priority(), f.selector().criteria(),
+                        printTreatment(f.treatment()));
+            } else {
+                ApplicationId appId = coreService.getAppId(f.appId());
+                print(LONG_FORMAT, Long.toHexString(f.id().value()), f.state(),
+                        f.bytes(), f.packets(), f.life(), f.liveType(), f.priority(), f.tableId(),
+                        appId != null ? appId.name() : "<none>",
+                        f.payLoad() == null ? null : Arrays.toString(f.payLoad().payLoad()),
+                        f.selector().criteria(), f.treatment());
+            }
+        }
+    }
+
+    private String printTreatment(TrafficTreatment treatment) {
+        final String delimiter = ", ";
+        StringBuilder builder = new StringBuilder("[");
+        if (!treatment.immediate().isEmpty()) {
+            builder.append("immediate=" + treatment.immediate() + delimiter);
+        }
+        if (!treatment.deferred().isEmpty()) {
+            builder.append("deferred=" + treatment.deferred() + delimiter);
+        }
+        if (treatment.clearedDeferred()) {
+            builder.append("clearDeferred" + delimiter);
+        }
+        if (treatment.tableTransition() != null) {
+            builder.append("transition=" + treatment.tableTransition() + delimiter);
+        }
+        if (treatment.metered() != null) {
+            builder.append("meter=" + treatment.metered() + delimiter);
+        }
+        if (treatment.writeMetadata() != null) {
+            builder.append("metadata=" + treatment.writeMetadata() + delimiter);
+        }
+        // Chop off last delimiter
+        builder.replace(builder.length() - delimiter.length(), builder.length(), "");
+        builder.append("]");
+        return builder.toString();
+    }
+
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostCompleter.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostCompleter.java
new file mode 100644
index 0000000..c8f6c44
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostCompleter.java
@@ -0,0 +1,66 @@
+/*
+ * 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.cli;
+
+import org.onosproject.cli.AbstractChoicesCompleter;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.onlab.osgi.DefaultServiceDirectory.getService;
+
+/**
+ * Virtual host completer.
+ *
+ * Assumes the first argument which can be parsed to a number is network id.
+ */
+public class VirtualHostCompleter extends AbstractChoicesCompleter {
+    @Override
+    protected List<String> choices() {
+        //parse argument list for network id
+        String[] argsArray = commandLine.getArguments();
+        for (String str : argsArray) {
+            if (str.matches("[0-9]+")) {
+                long networkId = Long.valueOf(str);
+                return getSortedVirtualHosts(networkId).stream()
+                        .map(virtualHost -> virtualHost.id().toString())
+                        .collect(Collectors.toList());
+            }
+        }
+        return Collections.singletonList("Missing network id");
+    }
+
+    /**
+     * Returns the list of virtual hosts sorted using the host identifier.
+     *
+     * @param networkId network id
+     * @return virtual host list
+     */
+    private List<VirtualHost> getSortedVirtualHosts(long networkId) {
+        VirtualNetworkService service = getService(VirtualNetworkService.class);
+
+        List<VirtualHost> virtualHosts = new ArrayList<>();
+        virtualHosts.addAll(service.getVirtualHosts(NetworkId.networkId(networkId)));
+        return virtualHosts;
+    }
+
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostCreateCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostCreateCommand.java
new file mode 100644
index 0000000..da198b1
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostCreateCommand.java
@@ -0,0 +1,91 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.action.Option;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Creates a new virtual host.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-create-host",
+        description = "Creates a new virtual host in a network.")
+public class VirtualHostCreateCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "mac", description = "Mac address",
+            required = true, multiValued = false)
+    String mac = null;
+
+    @Argument(index = 2, name = "vlan", description = "Vlan",
+            required = true, multiValued = false)
+    short vlan;
+
+    @Argument(index = 3, name = "hostLocationDeviceId", description = "Host location device ID",
+            required = true, multiValued = false)
+    String hostLocationDeviceId;
+
+    @Argument(index = 4, name = "hostLocationPortNumber", description = "Host location port number",
+            required = true, multiValued = false)
+    long hostLocationPortNumber;
+
+    // ip addresses
+    @Option(name = "--hostIp", description = "Host IP addresses.  Can be specified multiple times.",
+            required = false, multiValued = true)
+    protected String[] hostIpStrings;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+
+        Set<IpAddress> hostIps = new HashSet<>();
+        if (hostIpStrings != null) {
+            Arrays.stream(hostIpStrings).forEach(s -> hostIps.add(IpAddress.valueOf(s)));
+        }
+        HostLocation hostLocation = new HostLocation(DeviceId.deviceId(hostLocationDeviceId),
+                                                     PortNumber.portNumber(hostLocationPortNumber),
+                                                     System.currentTimeMillis());
+        MacAddress macAddress = MacAddress.valueOf(mac);
+        VlanId vlanId = VlanId.vlanId(vlan);
+        service.createVirtualHost(NetworkId.networkId(networkId),
+                                  HostId.hostId(macAddress, vlanId), macAddress, vlanId,
+                                  hostLocation, hostIps);
+        print("Virtual host successfully created.");
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostListCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostListCommand.java
new file mode 100644
index 0000000..38533ee
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostListCommand.java
@@ -0,0 +1,75 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Lists all virtual hosts for the network ID.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-hosts",
+        description = "Lists all virtual hosts in a virtual network.")
+public class VirtualHostListCommand extends AbstractShellCommand {
+
+    private static final String FMT_VIRTUAL_HOST =
+            "id=%s, mac=%s, vlan=%s, location=%s, ips=%s";
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Override
+    protected void doExecute() {
+        getSortedVirtualHosts().forEach(this::printVirtualHost);
+    }
+
+    /**
+     * Returns the list of virtual hosts sorted using the device identifier.
+     *
+     * @return virtual host list
+     */
+    private List<VirtualHost> getSortedVirtualHosts() {
+        VirtualNetworkService service = get(VirtualNetworkService.class);
+
+        List<VirtualHost> virtualHosts = new ArrayList<>();
+        virtualHosts.addAll(service.getVirtualHosts(NetworkId.networkId(networkId)));
+        return virtualHosts;
+    }
+
+    /**
+     * Prints out each virtual host.
+     *
+     * @param virtualHost virtual host
+     */
+    private void printVirtualHost(VirtualHost virtualHost) {
+        print(FMT_VIRTUAL_HOST, virtualHost.id().toString(), virtualHost.mac().toString(),
+              virtualHost.vlan().toString(), virtualHost.location().toString(),
+              virtualHost.ipAddresses().toString());
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostRemoveCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostRemoveCommand.java
new file mode 100644
index 0000000..329e4a3
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualHostRemoveCommand.java
@@ -0,0 +1,54 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.net.HostId;
+//import org.onosproject.net.HostId;
+
+/**
+ * Removes a virtual host.
+ */
+
+@Service
+@Command(scope = "onos", name = "vnet-remove-host",
+        description = "Removes a virtual host.")
+public class VirtualHostRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "id", description = "Host ID",
+              required = true, multiValued = false)
+    @Completion(VirtualHostCompleter.class)
+    String id = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        service.removeVirtualHost(NetworkId.networkId(networkId), HostId.hostId(id));
+        print("Virtual host successfully removed.");
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualLinkCreateCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualLinkCreateCommand.java
new file mode 100644
index 0000000..4bc6ea5
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualLinkCreateCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.action.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+/**
+ * Creates a new virtual link.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-create-link",
+        description = "Creates a new virtual link in a network.")
+public class VirtualLinkCreateCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "srcDeviceId", description = "Source device ID",
+            required = true, multiValued = false)
+    @Completion(VirtualDeviceCompleter.class)
+    String srcDeviceId = null;
+
+    @Argument(index = 2, name = "srcPortNum", description = "Source port number",
+            required = true, multiValued = false)
+    @Completion(VirtualPortCompleter.class)
+    Integer srcPortNum = null;
+
+    @Argument(index = 3, name = "dstDeviceId", description = "Destination device ID",
+            required = true, multiValued = false)
+    @Completion(VirtualDeviceCompleter.class)
+    String dstDeviceId = null;
+
+    @Argument(index = 4, name = "dstPortNum", description = "Destination port number",
+            required = true, multiValued = false)
+    @Completion(VirtualPortCompleter.class)
+    Integer dstPortNum = null;
+
+    @Option(name = "-b", aliases = "--bidirectional",
+            description = "If this argument is passed in then the virtual link created will be bidirectional, " +
+                    "otherwise the link will be unidirectional.",
+            required = false, multiValued = false)
+    boolean bidirectional = false;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        ConnectPoint src = new ConnectPoint(DeviceId.deviceId(srcDeviceId), PortNumber.portNumber(srcPortNum));
+        ConnectPoint dst = new ConnectPoint(DeviceId.deviceId(dstDeviceId), PortNumber.portNumber(dstPortNum));
+
+        service.createVirtualLink(NetworkId.networkId(networkId), src, dst);
+        if (bidirectional) {
+            service.createVirtualLink(NetworkId.networkId(networkId), dst, src);
+        }
+        print("Virtual link successfully created.");
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualLinkListCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualLinkListCommand.java
new file mode 100644
index 0000000..a69e0b7
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualLinkListCommand.java
@@ -0,0 +1,76 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Lists all virtual links for the network ID.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-links",
+        description = "Lists all virtual links in a virtual network.")
+public class VirtualLinkListCommand extends AbstractShellCommand {
+
+    private static final String FMT_VIRTUAL_LINK =
+            "src=%s, dst=%s, state=%s, tunnelId=%s";
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Override
+    protected void doExecute() {
+
+        getSortedVirtualLinks().forEach(this::printVirtualLink);
+    }
+
+    /**
+     * Returns the list of virtual links sorted using the device identifier.
+     *
+     * @return virtual link list
+     */
+    private List<VirtualLink> getSortedVirtualLinks() {
+        VirtualNetworkService service = get(VirtualNetworkService.class);
+
+        List<VirtualLink> virtualLinks = new ArrayList<>();
+        virtualLinks.addAll(service.getVirtualLinks(NetworkId.networkId(networkId)));
+        return virtualLinks;
+    }
+
+    /**
+     * Prints out each virtual link.
+     *
+     * @param virtualLink virtual link
+     */
+    private void printVirtualLink(VirtualLink virtualLink) {
+        print(FMT_VIRTUAL_LINK, virtualLink.src().toString(), virtualLink.dst().toString(),
+              virtualLink.state(),
+              virtualLink.tunnelId() == null ? null : virtualLink.tunnelId().toString());
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualLinkRemoveCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualLinkRemoveCommand.java
new file mode 100644
index 0000000..5f613f4
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualLinkRemoveCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.action.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+/**
+ * Removes a virtual link.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-remove-link",
+        description = "Removes a virtual link.")
+public class VirtualLinkRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "srcDeviceId", description = "Source device ID",
+            required = true, multiValued = false)
+    @Completion(VirtualDeviceCompleter.class)
+    String srcDeviceId = null;
+
+    @Argument(index = 2, name = "srcPortNum", description = "Source port number",
+            required = true, multiValued = false)
+    @Completion(VirtualPortCompleter.class)
+    Integer srcPortNum = null;
+
+    @Argument(index = 3, name = "dstDeviceId", description = "Destination device ID",
+            required = true, multiValued = false)
+    @Completion(VirtualDeviceCompleter.class)
+    String dstDeviceId = null;
+
+    @Argument(index = 4, name = "dstPortNum", description = "Destination port number",
+            required = true, multiValued = false)
+    @Completion(VirtualPortCompleter.class)
+    Integer dstPortNum = null;
+
+    @Option(name = "-b", aliases = "--bidirectional",
+            description = "If this argument is passed in then then bidirectional virtual link will be removed, " +
+                    "otherwise the unidirectional link will be removed.",
+            required = false, multiValued = false)
+    boolean bidirectional = false;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        ConnectPoint src = new ConnectPoint(DeviceId.deviceId(srcDeviceId), PortNumber.portNumber(srcPortNum));
+        ConnectPoint dst = new ConnectPoint(DeviceId.deviceId(dstDeviceId), PortNumber.portNumber(dstPortNum));
+
+        service.removeVirtualLink(NetworkId.networkId(networkId), src, dst);
+        if (bidirectional) {
+            service.removeVirtualLink(NetworkId.networkId(networkId), dst, src);
+        }
+        print("Virtual link successfully removed.");
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkBalanceMastersCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkBalanceMastersCommand.java
new file mode 100644
index 0000000..51a0c96
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkBalanceMastersCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2014-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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.mastership.MastershipAdminService;
+
+/**
+ * Forces virtual network device mastership rebalancing.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-balance-masters",
+        description = "Forces virtual network device mastership rebalancing")
+public class VirtualNetworkBalanceMastersCommand extends AbstractShellCommand {
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+    @Override
+    protected void doExecute() {
+        VirtualNetworkService vnetService = get(VirtualNetworkService.class);
+        MastershipAdminService mastershipAdminService = vnetService
+                .get(NetworkId.networkId(networkId), MastershipAdminService.class);
+        mastershipAdminService.balanceRoles();
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkCompleter.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkCompleter.java
new file mode 100644
index 0000000..1a3e7a2
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkCompleter.java
@@ -0,0 +1,62 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.Comparators;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+
+import java.util.List;
+import java.util.Set;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.SortedSet;
+
+/**
+ * Virtual network completer.
+ */
+@Service
+public class VirtualNetworkCompleter implements Completer {
+    @Override
+    public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+        // Delegate string completer
+        StringsCompleter delegate = new StringsCompleter();
+
+        // Fetch our service and feed it's offerings to the string completer
+        VirtualNetworkAdminService service = AbstractShellCommand.get(VirtualNetworkAdminService.class);
+
+        List<VirtualNetwork> virtualNetworks = new ArrayList<>();
+
+        Set<TenantId> tenantSet = service.getTenantIds();
+        tenantSet.forEach(tenantId -> virtualNetworks.addAll(service.getVirtualNetworks(tenantId)));
+
+        Collections.sort(virtualNetworks, Comparators.VIRTUAL_NETWORK_COMPARATOR);
+
+        SortedSet<String> strings = delegate.getStrings();
+        virtualNetworks.forEach(virtualNetwork -> strings.add(virtualNetwork.id().toString()));
+
+        // Now let the completer do the work for figuring out what to offer.
+        return delegate.complete(session, commandLine, candidates);
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkCreateCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkCreateCommand.java
new file mode 100644
index 0000000..d1ebe47
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkCreateCommand.java
@@ -0,0 +1,46 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+
+/**
+ * Creates a new virtual network.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-create",
+        description = "Creates a new virtual network.")
+public class VirtualNetworkCreateCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "id", description = "Tenant ID",
+            required = true, multiValued = false)
+    @Completion(TenantCompleter.class)
+    String id = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        service.createVirtualNetwork(TenantId.tenantId(id));
+        print("Virtual network successfully created.");
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkIntentCreateCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkIntentCreateCommand.java
new file mode 100644
index 0000000..4a8b400
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkIntentCreateCommand.java
@@ -0,0 +1,86 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.net.ConnectivityIntentCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+
+import java.util.List;
+
+/**
+ * Installs virtual network intents.
+ */
+@Service
+@Command(scope = "onos", name = "add-vnet-intent",
+        description = "Installs virtual network connectivity intent")
+public class VirtualNetworkIntentCreateCommand extends ConnectivityIntentCommand {
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "ingressDevice",
+            description = "Ingress Device/Port Description",
+            required = true, multiValued = false)
+    String ingressDeviceString = null;
+
+    @Argument(index = 2, name = "egressDevice",
+            description = "Egress Device/Port Description",
+            required = true, multiValued = false)
+    String egressDeviceString = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkService service = get(VirtualNetworkService.class);
+        IntentService virtualNetworkIntentService = service.get(NetworkId.networkId(networkId), IntentService.class);
+
+        ConnectPoint ingress = ConnectPoint.deviceConnectPoint(ingressDeviceString);
+        ConnectPoint egress = ConnectPoint.deviceConnectPoint(egressDeviceString);
+
+        TrafficSelector selector = buildTrafficSelector();
+        TrafficTreatment treatment = buildTrafficTreatment();
+
+        List<Constraint> constraints = buildConstraints();
+
+        Intent intent = VirtualNetworkIntent.builder()
+                .networkId(NetworkId.networkId(networkId))
+                .appId(appId())
+                .key(key())
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(ingress)
+                .egressPoint(egress)
+                .constraints(constraints)
+                .priority(priority())
+                .build();
+        virtualNetworkIntentService.submit(intent);
+        print("Virtual intent submitted:\n%s", intent.toString());
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkIntentRemoveCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkIntentRemoveCommand.java
new file mode 100644
index 0000000..eea3d45
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkIntentRemoveCommand.java
@@ -0,0 +1,190 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.action.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.Key;
+
+import java.math.BigInteger;
+import java.util.EnumSet;
+import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.onosproject.net.intent.IntentState.FAILED;
+import static org.onosproject.net.intent.IntentState.WITHDRAWN;
+
+/**
+ * Removes a virtual network intent.
+ */
+@Service
+@Command(scope = "onos", name = "remove-vnet-intent",
+        description = "Removes the virtual network intent")
+public class VirtualNetworkIntentRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "app",
+            description = "Application ID",
+            required = false, multiValued = false)
+    String applicationIdString = null;
+
+    @Argument(index = 2, name = "key",
+            description = "Intent Key",
+            required = false, multiValued = false)
+    String keyString = null;
+
+    @Option(name = "-p", aliases = "--purge",
+            description = "Purge the intent from the store after removal",
+            required = false, multiValued = false)
+    private boolean purgeAfterRemove = false;
+
+    @Option(name = "-s", aliases = "--sync",
+            description = "Waits for the removal before returning",
+            required = false, multiValued = false)
+    private boolean sync = false;
+
+    private static final EnumSet<IntentState> CAN_PURGE = EnumSet.of(WITHDRAWN, FAILED);
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkService service = get(VirtualNetworkService.class);
+        IntentService intentService = service.get(NetworkId.networkId(networkId), IntentService.class);
+        CoreService coreService = get(CoreService.class);
+
+        if (purgeAfterRemove || sync) {
+            print("Using \"sync\" to remove/purge intents - this may take a while...");
+            print("Check \"summary\" to see remove/purge progress.");
+        }
+
+        ApplicationId appId = appId();
+        if (!isNullOrEmpty(applicationIdString)) {
+            appId = coreService.getAppId(applicationIdString);
+            if (appId == null) {
+                print("Cannot find application Id %s", applicationIdString);
+                return;
+            }
+        }
+
+        if (isNullOrEmpty(keyString)) {
+            for (Intent intent : intentService.getIntents()) {
+                if (intent.appId().equals(appId)) {
+                    removeIntent(intentService, intent);
+                }
+            }
+
+        } else {
+            final Key key;
+            if (keyString.startsWith("0x")) {
+                // The intent uses a LongKey
+                keyString = keyString.replaceFirst("0x", "");
+                key = Key.of(new BigInteger(keyString, 16).longValue(), appId);
+            } else {
+                // The intent uses a StringKey
+                key = Key.of(keyString, appId);
+            }
+
+            Intent intent = intentService.getIntent(key);
+            if (intent != null) {
+                removeIntent(intentService, intent);
+            } else {
+                print("Intent not found!");
+            }
+        }
+    }
+
+    /**
+     * Removes the intent using the specified intentService.
+     *
+     * @param intentService intent service
+     * @param intent        intent
+     */
+    private void removeIntent(IntentService intentService, Intent intent) {
+        IntentListener listener = null;
+        Key key = intent.key();
+        final CountDownLatch withdrawLatch, purgeLatch;
+        if (purgeAfterRemove || sync) {
+            // set up latch and listener to track uninstall progress
+            withdrawLatch = new CountDownLatch(1);
+            purgeLatch = purgeAfterRemove ? new CountDownLatch(1) : null;
+            listener = (IntentEvent event) -> {
+                if (Objects.equals(event.subject().key(), key)) {
+                    if (event.type() == IntentEvent.Type.WITHDRAWN ||
+                            event.type() == IntentEvent.Type.FAILED) {
+                        withdrawLatch.countDown();
+                    } else if (purgeLatch != null && purgeAfterRemove &&
+                            event.type() == IntentEvent.Type.PURGED) {
+                        purgeLatch.countDown();
+                    }
+                }
+            };
+            intentService.addListener(listener);
+        } else {
+            purgeLatch = null;
+            withdrawLatch = null;
+        }
+
+        // request the withdraw
+        intentService.withdraw(intent);
+
+        if ((purgeAfterRemove || sync) && purgeLatch != null) {
+            try { // wait for withdraw event
+                withdrawLatch.await(5, TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+                print("Timed out waiting for intent {} withdraw", key);
+            }
+            if (purgeAfterRemove && CAN_PURGE.contains(intentService.getIntentState(key))) {
+                intentService.purge(intent);
+                if (sync) { // wait for purge event
+                    /* TODO
+                       Technically, the event comes before map.remove() is called.
+                       If we depend on sync and purge working together, we will
+                       need to address this.
+                    */
+                    try {
+                        purgeLatch.await(5, TimeUnit.SECONDS);
+                    } catch (InterruptedException e) {
+                        print("Timed out waiting for intent {} purge", key);
+                    }
+                }
+            }
+        }
+
+        if (listener != null) {
+            // clean up the listener
+            intentService.removeListener(listener);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkListCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkListCommand.java
new file mode 100644
index 0000000..df1172c
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkListCommand.java
@@ -0,0 +1,77 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.Comparators;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Lists all virtual networks for the tenant ID.
+ */
+@Service
+@Command(scope = "onos", name = "vnets",
+        description = "Lists all virtual networks.")
+public class VirtualNetworkListCommand extends AbstractShellCommand {
+
+    private static final String FMT_VIRTUAL_NETWORK =
+            "tenantId=%s, networkId=%s";
+
+    @Override
+    protected void doExecute() {
+
+        getSortedVirtualNetworks().forEach(this::printVirtualNetwork);
+    }
+
+    /**
+     * Returns the list of virtual networks sorted using the tenant identifier.
+     *
+     * @return sorted virtual network list
+     */
+    private List<VirtualNetwork> getSortedVirtualNetworks() {
+        VirtualNetworkService service = get(VirtualNetworkService.class);
+        VirtualNetworkAdminService adminService = get(VirtualNetworkAdminService.class);
+
+        List<VirtualNetwork> virtualNetworks = new ArrayList<>();
+
+        Set<TenantId> tenantSet = adminService.getTenantIds();
+        tenantSet.forEach(tenantId -> virtualNetworks.addAll(service.getVirtualNetworks(tenantId)));
+
+        Collections.sort(virtualNetworks, Comparators.VIRTUAL_NETWORK_COMPARATOR);
+        return virtualNetworks;
+    }
+
+    /**
+     * Prints out each virtual network.
+     *
+     * @param virtualNetwork virtual network
+     */
+    private void printVirtualNetwork(VirtualNetwork virtualNetwork) {
+        print(FMT_VIRTUAL_NETWORK, virtualNetwork.tenantId(), virtualNetwork.id());
+    }
+}
+
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkPacketRequestCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkPacketRequestCommand.java
new file mode 100644
index 0000000..059829d
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkPacketRequestCommand.java
@@ -0,0 +1,323 @@
+/*
+ * 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.cli;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.action.Option;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.TpPort;
+import org.onlab.packet.VlanId;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cli.net.EthType;
+import org.onosproject.cli.net.EthTypeCompleter;
+import org.onosproject.cli.net.ExtHeader;
+import org.onosproject.cli.net.ExtHeaderCompleter;
+import org.onosproject.cli.net.Icmp6Code;
+import org.onosproject.cli.net.Icmp6CodeCompleter;
+import org.onosproject.cli.net.Icmp6Type;
+import org.onosproject.cli.net.Icmp6TypeCompleter;
+import org.onosproject.cli.net.IpProtocol;
+import org.onosproject.cli.net.IpProtocolCompleter;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketRequest;
+import org.onosproject.net.packet.PacketService;
+
+import java.util.List;
+import java.util.Optional;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+
+/**
+ * Tests virtual network packet requests.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-packet",
+        description = "Tests virtual network packet requests")
+public class VirtualNetworkPacketRequestCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "command",
+            description = "Command name (requestPackets|getRequests|cancelPackets)",
+            required = true, multiValued = false)
+    private String command = null;
+
+    @Argument(index = 1, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    private Long networkId = null;
+
+    @Option(name = "--deviceId", description = "Device ID",
+            required = false, multiValued = false)
+    private String deviceIdString = null;
+
+    // Traffic selector
+    @Option(name = "-s", aliases = "--ethSrc", description = "Source MAC Address",
+            required = false, multiValued = false)
+    private String srcMacString = null;
+
+    @Option(name = "-d", aliases = "--ethDst", description = "Destination MAC Address",
+            required = false, multiValued = false)
+    private String dstMacString = null;
+
+    @Option(name = "-t", aliases = "--ethType", description = "Ethernet Type",
+            required = false, multiValued = false)
+    @Completion(EthTypeCompleter.class)
+    private String ethTypeString = null;
+
+    @Option(name = "-v", aliases = "--vlan", description = "VLAN ID",
+            required = false, multiValued = false)
+    private String vlanString = null;
+
+    @Option(name = "--ipProto", description = "IP Protocol",
+            required = false, multiValued = false)
+    @Completion(IpProtocolCompleter.class)
+    private String ipProtoString = null;
+
+    @Option(name = "--ipSrc", description = "Source IP Prefix",
+            required = false, multiValued = false)
+    private String srcIpString = null;
+
+    @Option(name = "--ipDst", description = "Destination IP Prefix",
+            required = false, multiValued = false)
+    private String dstIpString = null;
+
+    @Option(name = "--fLabel", description = "IPv6 Flow Label",
+            required = false, multiValued = false)
+    private String fLabelString = null;
+
+    @Option(name = "--icmp6Type", description = "ICMPv6 Type",
+            required = false, multiValued = false)
+    @Completion(Icmp6TypeCompleter.class)
+    private String icmp6TypeString = null;
+
+    @Option(name = "--icmp6Code", description = "ICMPv6 Code",
+            required = false, multiValued = false)
+    @Completion(Icmp6CodeCompleter.class)
+    private String icmp6CodeString = null;
+
+    @Option(name = "--ndTarget", description = "IPv6 Neighbor Discovery Target Address",
+            required = false, multiValued = false)
+    private String ndTargetString = null;
+
+    @Option(name = "--ndSLL", description = "IPv6 Neighbor Discovery Source Link-Layer",
+            required = false, multiValued = false)
+    private String ndSllString = null;
+
+    @Option(name = "--ndTLL", description = "IPv6 Neighbor Discovery Target Link-Layer",
+            required = false, multiValued = false)
+    private String ndTllString = null;
+
+    @Option(name = "--tcpSrc", description = "Source TCP Port",
+            required = false, multiValued = false)
+    private String srcTcpString = null;
+
+    @Option(name = "--tcpDst", description = "Destination TCP Port",
+            required = false, multiValued = false)
+    private String dstTcpString = null;
+
+    @Option(name = "--extHdr", description = "IPv6 Extension Header Pseudo-field",
+            required = false, multiValued = true)
+    @Completion(ExtHeaderCompleter.class)
+    private List<String> extHdrStringList = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkService service = get(VirtualNetworkService.class);
+        PacketService virtualPacketService = service.get(NetworkId.networkId(networkId), PacketService.class);
+
+        if (command == null) {
+            print("Command is not defined");
+            return;
+        }
+
+        if (command.equals("getRequests")) {
+            getRequests(virtualPacketService);
+            return;
+        }
+
+        TrafficSelector selector = buildTrafficSelector();
+        PacketPriority packetPriority = PacketPriority.CONTROL; //TODO allow user to specify
+        Optional<DeviceId> optionalDeviceId = null;
+        if (!isNullOrEmpty(deviceIdString)) {
+            optionalDeviceId = Optional.of(DeviceId.deviceId(deviceIdString));
+        }
+
+        if (command.equals("requestPackets")) {
+            if (optionalDeviceId != null) {
+                virtualPacketService.requestPackets(selector, packetPriority, appId(), optionalDeviceId);
+            } else {
+                virtualPacketService.requestPackets(selector, packetPriority, appId());
+            }
+            print("Virtual packet requested:\n%s", selector);
+            return;
+        }
+
+       if (command.equals("cancelPackets")) {
+            if (optionalDeviceId != null) {
+                virtualPacketService.cancelPackets(selector, packetPriority, appId(), optionalDeviceId);
+            } else {
+                virtualPacketService.cancelPackets(selector, packetPriority, appId());
+            }
+            print("Virtual packet cancelled:\n%s", selector);
+            return;
+        }
+
+        print("Unsupported command %s", command);
+    }
+
+    private void getRequests(PacketService packetService) {
+        List<PacketRequest> packetRequests = packetService.getRequests();
+        if (outputJson()) {
+            print("%s", json(packetRequests));
+        } else {
+            packetRequests.forEach(packetRequest -> print(packetRequest.toString()));
+        }
+    }
+
+    private JsonNode json(List<PacketRequest> packetRequests) {
+        ObjectMapper mapper = new ObjectMapper();
+        ArrayNode result = mapper.createArrayNode();
+        packetRequests.forEach(packetRequest ->
+                                       result.add(jsonForEntity(packetRequest, PacketRequest.class)));
+        return result;
+    }
+
+    /**
+     * Constructs a traffic selector based on the command line arguments
+     * presented to the command.
+     * @return traffic selector
+     */
+    private TrafficSelector buildTrafficSelector() {
+        IpPrefix srcIpPrefix = null;
+        IpPrefix dstIpPrefix = null;
+
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+
+        if (!isNullOrEmpty(srcIpString)) {
+            srcIpPrefix = IpPrefix.valueOf(srcIpString);
+            if (srcIpPrefix.isIp4()) {
+                selectorBuilder.matchIPSrc(srcIpPrefix);
+            } else {
+                selectorBuilder.matchIPv6Src(srcIpPrefix);
+            }
+        }
+
+        if (!isNullOrEmpty(dstIpString)) {
+            dstIpPrefix = IpPrefix.valueOf(dstIpString);
+            if (dstIpPrefix.isIp4()) {
+                selectorBuilder.matchIPDst(dstIpPrefix);
+            } else {
+                selectorBuilder.matchIPv6Dst(dstIpPrefix);
+            }
+        }
+
+        if ((srcIpPrefix != null) && (dstIpPrefix != null) &&
+            (srcIpPrefix.version() != dstIpPrefix.version())) {
+            // ERROR: IP src/dst version mismatch
+            throw new IllegalArgumentException(
+                        "IP source and destination version mismatch");
+        }
+
+        //
+        // Set the default EthType based on the IP version if the matching
+        // source or destination IP prefixes.
+        //
+        Short ethType = null;
+        if ((srcIpPrefix != null) && srcIpPrefix.isIp6()) {
+            ethType = EthType.IPV6.value();
+        }
+        if ((dstIpPrefix != null) && dstIpPrefix.isIp6()) {
+            ethType = EthType.IPV6.value();
+        }
+        if (!isNullOrEmpty(ethTypeString)) {
+            ethType = EthType.parseFromString(ethTypeString);
+        }
+        if (ethType != null) {
+            selectorBuilder.matchEthType(ethType);
+        }
+        if (!isNullOrEmpty(vlanString)) {
+            selectorBuilder.matchVlanId(VlanId.vlanId(Short.parseShort(vlanString)));
+        }
+        if (!isNullOrEmpty(srcMacString)) {
+            selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMacString));
+        }
+
+        if (!isNullOrEmpty(dstMacString)) {
+            selectorBuilder.matchEthDst(MacAddress.valueOf(dstMacString));
+        }
+
+        if (!isNullOrEmpty(ipProtoString)) {
+            short ipProtoShort = IpProtocol.parseFromString(ipProtoString);
+            selectorBuilder.matchIPProtocol((byte) ipProtoShort);
+        }
+
+        if (!isNullOrEmpty(fLabelString)) {
+            selectorBuilder.matchIPv6FlowLabel(Integer.parseInt(fLabelString));
+        }
+
+        if (!isNullOrEmpty(icmp6TypeString)) {
+            byte icmp6Type = Icmp6Type.parseFromString(icmp6TypeString);
+            selectorBuilder.matchIcmpv6Type(icmp6Type);
+        }
+
+        if (!isNullOrEmpty(icmp6CodeString)) {
+            byte icmp6Code = Icmp6Code.parseFromString(icmp6CodeString);
+            selectorBuilder.matchIcmpv6Code(icmp6Code);
+        }
+
+        if (!isNullOrEmpty(ndTargetString)) {
+            selectorBuilder.matchIPv6NDTargetAddress(Ip6Address.valueOf(ndTargetString));
+        }
+
+        if (!isNullOrEmpty(ndSllString)) {
+            selectorBuilder.matchIPv6NDSourceLinkLayerAddress(MacAddress.valueOf(ndSllString));
+        }
+
+        if (!isNullOrEmpty(ndTllString)) {
+            selectorBuilder.matchIPv6NDTargetLinkLayerAddress(MacAddress.valueOf(ndTllString));
+        }
+
+        if (!isNullOrEmpty(srcTcpString)) {
+            selectorBuilder.matchTcpSrc(TpPort.tpPort(Integer.parseInt(srcTcpString)));
+        }
+
+        if (!isNullOrEmpty(dstTcpString)) {
+            selectorBuilder.matchTcpDst(TpPort.tpPort(Integer.parseInt(dstTcpString)));
+        }
+
+        if (extHdrStringList != null) {
+            short extHdr = 0;
+            for (String extHdrString : extHdrStringList) {
+                extHdr = (short) (extHdr | ExtHeader.parseFromString(extHdrString));
+            }
+            selectorBuilder.matchIPv6ExthdrFlags(extHdr);
+        }
+
+        return selectorBuilder.build();
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkRemoveCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkRemoveCommand.java
new file mode 100644
index 0000000..2b28044
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualNetworkRemoveCommand.java
@@ -0,0 +1,46 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+
+/**
+ * Removes a virtual network.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-remove",
+        description = "Removes a virtual network.")
+public class VirtualNetworkRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "id", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long id;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        service.removeVirtualNetwork(NetworkId.networkId(id));
+        print("Virtual network successfully removed.");
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortBindCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortBindCommand.java
new file mode 100644
index 0000000..7013a01
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortBindCommand.java
@@ -0,0 +1,99 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cli.net.DeviceIdCompleter;
+import org.onosproject.cli.net.PortNumberCompleter;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Binds an existing virtual port with a physical port.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-bind-port",
+        description = "Binds an existing virtual port with a physical port.")
+public class VirtualPortBindCommand extends AbstractShellCommand {
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "deviceId", description = "Virtual Device ID",
+            required = true, multiValued = false)
+    @Completion(VirtualDeviceCompleter.class)
+    String deviceId = null;
+
+    @Argument(index = 2, name = "portNum", description = "Virtual device port number",
+            required = true, multiValued = false)
+    @Completion(VirtualPortCompleter.class)
+    Integer portNum = null;
+
+    @Argument(index = 3, name = "physDeviceId", description = "Physical Device ID",
+            required = true, multiValued = false)
+    @Completion(DeviceIdCompleter.class)
+    String physDeviceId = null;
+
+    @Argument(index = 4, name = "physPortNum", description = "Physical device port number",
+            required = true, multiValued = false)
+    @Completion(PortNumberCompleter.class)
+    Integer physPortNum = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        DeviceService deviceService = get(DeviceService.class);
+
+        VirtualPort vPort = getVirtualPort(PortNumber.portNumber(portNum));
+        checkNotNull(vPort, "The virtual Port does not exist");
+
+        ConnectPoint realizedBy = new ConnectPoint(DeviceId.deviceId(physDeviceId),
+                                      PortNumber.portNumber(physPortNum));
+        service.bindVirtualPort(NetworkId.networkId(networkId), DeviceId.deviceId(deviceId),
+                                  PortNumber.portNumber(portNum), realizedBy);
+        print("Virtual port is successfully bound.");
+    }
+
+    /**
+     * Returns the virtual port matching the device and port identifier.
+     *
+     * @param aPortNumber port identifier
+     * @return matching virtual port, or null.
+     */
+    private VirtualPort getVirtualPort(PortNumber aPortNumber) {
+        VirtualNetworkService service = get(VirtualNetworkService.class);
+        Set<VirtualPort> ports = service.getVirtualPorts(NetworkId.networkId(networkId),
+                                                    DeviceId.deviceId(deviceId));
+        return ports.stream().filter(p -> p.number().equals(aPortNumber))
+                .findFirst().get();
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortCompleter.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortCompleter.java
new file mode 100644
index 0000000..141c964
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortCompleter.java
@@ -0,0 +1,75 @@
+/*
+ * 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.cli;
+
+import static org.onlab.osgi.DefaultServiceDirectory.getService;
+
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractChoicesCompleter;
+import org.onosproject.incubator.net.virtual.Comparators;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.DeviceId;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+/**
+ * Virtual port completer.
+ *
+ * Assumes the first argument which can be parsed to a number is network id
+ * and the argument right before the one being completed is device id
+ */
+@Service
+public class VirtualPortCompleter extends AbstractChoicesCompleter {
+    @Override
+    protected List<String> choices() {
+        //parse argument list for network id
+        String[] argsArray = commandLine.getArguments();
+        for (String str : argsArray) {
+            if (str.matches("[0-9]+")) {
+                long networkId = Long.valueOf(str);
+                String deviceId = argsArray[argsArray.length - 1];
+                return getSortedVirtualPorts(networkId, deviceId).stream()
+                        .map(virtualPort -> virtualPort.number().toString())
+                        .collect(Collectors.toList());
+            }
+        }
+
+        return Collections.singletonList("Missing network id");
+    }
+
+    /**
+     * Returns the list of virtual ports sorted using the port number.
+     *
+     * @param networkId network id.
+     * @param deviceId device id
+     * @return sorted virtual port list
+     */
+    private List<VirtualPort> getSortedVirtualPorts(long networkId, String deviceId) {
+        VirtualNetworkService service = getService(VirtualNetworkService.class);
+
+        List<VirtualPort> virtualPorts = new ArrayList<>();
+        virtualPorts.addAll(service.getVirtualPorts(NetworkId.networkId(networkId),
+                DeviceId.deviceId(deviceId)));
+        Collections.sort(virtualPorts, Comparators.VIRTUAL_PORT_COMPARATOR);
+        return virtualPorts;
+    }
+
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortCreateCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortCreateCommand.java
new file mode 100644
index 0000000..a466a64
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortCreateCommand.java
@@ -0,0 +1,110 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cli.net.DeviceIdCompleter;
+import org.onosproject.cli.net.PortNumberCompleter;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Creates a new virtual port.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-create-port",
+        description = "Creates a new virtual port in a network.")
+public class VirtualPortCreateCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "deviceId", description = "Virtual Device ID",
+            required = true, multiValued = false)
+    @Completion(VirtualDeviceCompleter.class)
+    String deviceId = null;
+
+    @Argument(index = 2, name = "portNum", description = "Virtual device port number",
+            required = true, multiValued = false)
+    Integer portNum = null;
+
+    @Argument(index = 3, name = "physDeviceId", description = "Physical Device ID",
+            required = false, multiValued = false)
+    @Completion(DeviceIdCompleter.class)
+    String physDeviceId = null;
+
+    @Argument(index = 4, name = "physPortNum", description = "Physical device port number",
+            required = false, multiValued = false)
+    @Completion(PortNumberCompleter.class)
+    Integer physPortNum = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        DeviceService deviceService = get(DeviceService.class);
+
+        VirtualDevice virtualDevice = getVirtualDevice(DeviceId.deviceId(deviceId));
+        checkNotNull(virtualDevice, "The virtual device does not exist.");
+
+        ConnectPoint realizedBy = null;
+        if (physDeviceId != null && physPortNum != null) {
+            checkNotNull(physPortNum, "The physical port does not specified.");
+            realizedBy = new ConnectPoint(DeviceId.deviceId(physDeviceId),
+                                               PortNumber.portNumber(physPortNum));
+            checkNotNull(realizedBy, "The physical port does not exist.");
+        }
+
+        service.createVirtualPort(NetworkId.networkId(networkId), DeviceId.deviceId(deviceId),
+                                  PortNumber.portNumber(portNum), realizedBy);
+        print("Virtual port successfully created.");
+    }
+
+    /**
+     * Returns the virtual device matching the device identifier.
+     *
+     * @param aDeviceId device identifier
+     * @return matching virtual device, or null.
+     */
+    private VirtualDevice getVirtualDevice(DeviceId aDeviceId) {
+        VirtualNetworkService service = get(VirtualNetworkService.class);
+
+        Set<VirtualDevice> virtualDevices = service.getVirtualDevices(NetworkId.networkId(networkId));
+
+        for (VirtualDevice virtualDevice : virtualDevices) {
+            if (virtualDevice.id().equals(aDeviceId)) {
+                return virtualDevice;
+            }
+        }
+        return null;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortListCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortListCommand.java
new file mode 100644
index 0000000..f7a6c08
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortListCommand.java
@@ -0,0 +1,91 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.Comparators;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.DeviceId;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Lists all virtual ports for the network ID.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-ports",
+        description = "Lists all virtual ports in a virtual network.")
+public class VirtualPortListCommand extends AbstractShellCommand {
+
+    private static final String FMT_VIRTUAL_PORT =
+            "virtual portNumber=%s, physical deviceId=%s, portNumber=%s, isEnabled=%s";
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "deviceId", description = "Virtual Device ID",
+            required = true, multiValued = false)
+    @Completion(VirtualDeviceCompleter.class)
+    String deviceId = null;
+
+    @Override
+    protected void doExecute() {
+
+        getSortedVirtualPorts().forEach(this::printVirtualPort);
+    }
+
+    /**
+     * Returns the list of virtual ports sorted using the network identifier.
+     *
+     * @return sorted virtual port list
+     */
+    private List<VirtualPort> getSortedVirtualPorts() {
+        VirtualNetworkService service = get(VirtualNetworkService.class);
+
+        List<VirtualPort> virtualPorts = new ArrayList<>();
+        virtualPorts.addAll(service.getVirtualPorts(NetworkId.networkId(networkId),
+                                                    DeviceId.deviceId(deviceId)));
+        Collections.sort(virtualPorts, Comparators.VIRTUAL_PORT_COMPARATOR);
+        return virtualPorts;
+    }
+
+    /**
+     * Prints out each virtual port.
+     *
+     * @param virtualPort virtual port
+     */
+    private void printVirtualPort(VirtualPort virtualPort) {
+        if (virtualPort.realizedBy() == null) {
+            print(FMT_VIRTUAL_PORT, virtualPort.number(), "None", "None", virtualPort.isEnabled());
+        } else {
+            print(FMT_VIRTUAL_PORT, virtualPort.number(),
+                  virtualPort.realizedBy().deviceId(),
+                  virtualPort.realizedBy().port(),
+                  virtualPort.isEnabled());
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortRemoveCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortRemoveCommand.java
new file mode 100644
index 0000000..6c79276
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortRemoveCommand.java
@@ -0,0 +1,59 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+/**
+ * Removes a virtual port.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-remove-port",
+        description = "Removes a virtual port.")
+public class VirtualPortRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "deviceId", description = "Device ID",
+            required = true, multiValued = false)
+    @Completion(VirtualDeviceCompleter.class)
+    String deviceId = null;
+
+    @Argument(index = 2, name = "portNum", description = "Device port number",
+            required = true, multiValued = false)
+    @Completion(VirtualPortCompleter.class)
+    Integer portNum = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+        service.removeVirtualPort(NetworkId.networkId(networkId), DeviceId.deviceId(deviceId),
+                                  PortNumber.portNumber(portNum));
+        print("Virtual port successfully removed.");
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortStateCommand.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortStateCommand.java
new file mode 100644
index 0000000..56af2ba
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/VirtualPortStateCommand.java
@@ -0,0 +1,97 @@
+/*
+ * 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.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Administratively enables or disables state of an existing virtual port.
+ */
+@Service
+@Command(scope = "onos", name = "vnet-port-state",
+        description = "Administratively enables or disables state of an existing virtual port.")
+public class VirtualPortStateCommand extends AbstractShellCommand {
+    @Argument(index = 0, name = "networkId", description = "Network ID",
+            required = true, multiValued = false)
+    @Completion(VirtualNetworkCompleter.class)
+    Long networkId = null;
+
+    @Argument(index = 1, name = "deviceId", description = "Virtual Device ID",
+            required = true, multiValued = false)
+    @Completion(VirtualDeviceCompleter.class)
+    String deviceId = null;
+
+    @Argument(index = 2, name = "portNum", description = "Virtual device port number",
+            required = true, multiValued = false)
+    @Completion(VirtualPortCompleter.class)
+    Integer portNum = null;
+
+    @Argument(index = 3, name = "portState",
+            description = "Desired State. Either \"enable\" or \"disable\".",
+            required = true, multiValued = false)
+    String portState = null;
+
+    @Override
+    protected void doExecute() {
+        VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class);
+
+        VirtualPort vPort = getVirtualPort(PortNumber.portNumber(portNum));
+        checkNotNull(vPort, "The virtual Port does not exist");
+
+        boolean isEnabled;
+        if ("enable".equals(portState)) {
+            isEnabled = true;
+        } else if ("disable".equals(portState)) {
+            isEnabled = false;
+        } else {
+            print("State must be enable or disable");
+            return;
+        }
+
+        service.updatePortState(NetworkId.networkId(networkId),
+                                DeviceId.deviceId(deviceId), vPort.number(), isEnabled);
+        print("Virtual port state updated.");
+    }
+
+    /**
+     * Returns the virtual port matching the device and port identifier.
+     *
+     * @param aPortNumber port identifier
+     * @return matching virtual port, or null.
+     */
+    private VirtualPort getVirtualPort(PortNumber aPortNumber) {
+        VirtualNetworkService service = get(VirtualNetworkService.class);
+        Set<VirtualPort> ports = service.getVirtualPorts(NetworkId.networkId(networkId),
+                                                    DeviceId.deviceId(deviceId));
+        return ports.stream().filter(p -> p.number().equals(aPortNumber))
+                .findFirst().get();
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/package-info.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/package-info.java
new file mode 100644
index 0000000..049ee4f
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * CLI commands for querying and administering virtual networks.
+ */
+package org.onosproject.incubator.net.virtual.cli;
\ No newline at end of file
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManager.java
new file mode 100644
index 0000000..21ba3b9
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManager.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2018-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.ImmutableList;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkListener;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
+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.DeviceEvent;
+import org.onosproject.net.device.DeviceEvent.Type;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.PortStatistics;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Device service implementation built on the virtual network service.
+ */
+public class VirtualNetworkDeviceManager
+        extends AbstractVirtualListenerManager<DeviceEvent, DeviceListener>
+        implements DeviceService {
+
+    private static final String TYPE_NULL = "Type cannot be null";
+    private static final String DEVICE_NULL = "Device cannot be null";
+    private static final String PORT_NUMBER_NULL = "PortNumber cannot be null";
+    private VirtualNetworkListener virtualNetworkListener = new InternalVirtualNetworkListener();
+
+    /**
+     * Creates a new VirtualNetworkDeviceService object.
+     *
+     * @param virtualNetworkManager virtual network manager service
+     * @param networkId a virtual network identifier
+     */
+    public VirtualNetworkDeviceManager(VirtualNetworkService virtualNetworkManager,
+                                       NetworkId networkId) {
+        super(virtualNetworkManager, networkId, DeviceEvent.class);
+        manager.addListener(virtualNetworkListener);
+    }
+
+    @Override
+    public int getDeviceCount() {
+        return manager.getVirtualDevices(this.networkId).size();
+    }
+
+    @Override
+    public Iterable<Device> getDevices() {
+        return manager.getVirtualDevices(
+                this.networkId).stream().collect(Collectors.toSet());
+    }
+
+    @Override
+    public Iterable<Device> getDevices(Device.Type type) {
+        checkNotNull(type, TYPE_NULL);
+        return manager.getVirtualDevices(this.networkId)
+                .stream()
+                .filter(device -> type.equals(device.type()))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public Iterable<Device> getAvailableDevices() {
+        return getDevices();
+    }
+
+    @Override
+    public Iterable<Device> getAvailableDevices(Device.Type type) {
+        return getDevices(type);
+    }
+
+    @Override
+    public Device getDevice(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_NULL);
+        Optional<VirtualDevice> foundDevice =
+                manager.getVirtualDevices(this.networkId)
+                .stream()
+                .filter(device -> deviceId.equals(device.id()))
+                .findFirst();
+        if (foundDevice.isPresent()) {
+            return foundDevice.get();
+        }
+        return null;
+    }
+
+    @Override
+    public MastershipRole getRole(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_NULL);
+        // TODO hard coded to master for now.
+        return MastershipRole.MASTER;
+    }
+
+    @Override
+    public List<Port> getPorts(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_NULL);
+        return manager.getVirtualPorts(this.networkId, deviceId)
+                .stream()
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public List<PortStatistics> getPortStatistics(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_NULL);
+        // TODO not supported at the moment.
+        return ImmutableList.of();
+    }
+
+    @Override
+    public List<PortStatistics> getPortDeltaStatistics(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_NULL);
+        // TODO not supported at the moment.
+        return ImmutableList.of();
+    }
+
+    @Override
+    public PortStatistics getStatisticsForPort(DeviceId deviceId,
+                                               PortNumber portNumber) {
+        checkNotNull(deviceId, DEVICE_NULL);
+        checkNotNull(deviceId, PORT_NUMBER_NULL);
+        // TODO not supported at the moment.
+        return null;
+    }
+
+    @Override
+    public PortStatistics getDeltaStatisticsForPort(DeviceId deviceId,
+                                                    PortNumber portNumber) {
+        checkNotNull(deviceId, DEVICE_NULL);
+        checkNotNull(deviceId, PORT_NUMBER_NULL);
+        // TODO not supported at the moment.
+        return null;
+    }
+
+    @Override
+    public Port getPort(DeviceId deviceId, PortNumber portNumber) {
+        checkNotNull(deviceId, DEVICE_NULL);
+
+        Optional<VirtualPort> foundPort =
+                manager.getVirtualPorts(this.networkId, deviceId)
+                .stream()
+                .filter(port -> port.number().equals(portNumber))
+                .findFirst();
+        if (foundPort.isPresent()) {
+            return foundPort.get();
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isAvailable(DeviceId deviceId) {
+        return getDevice(deviceId) != null;
+    }
+
+    @Override
+    public String localStatus(DeviceId deviceId) {
+        // TODO not supported at this time
+        return null;
+    }
+
+    @Override
+    public long getLastUpdatedInstant(DeviceId deviceId) {
+        // TODO not supported at this time
+        return 0;
+    }
+
+    /**
+     * Translates VirtualNetworkEvent to DeviceEvent.
+     */
+    private class InternalVirtualNetworkListener implements VirtualNetworkListener {
+        @Override
+        public boolean isRelevant(VirtualNetworkEvent event) {
+            return networkId().equals(event.subject());
+        }
+
+        @Override
+        public void event(VirtualNetworkEvent event) {
+            switch (event.type()) {
+                case VIRTUAL_DEVICE_ADDED:
+                    post(new DeviceEvent(Type.DEVICE_ADDED, event.virtualDevice()));
+                    break;
+                case VIRTUAL_DEVICE_UPDATED:
+                    post(new DeviceEvent(Type.DEVICE_UPDATED, event.virtualDevice()));
+                    break;
+                case VIRTUAL_DEVICE_REMOVED:
+                    post(new DeviceEvent(Type.DEVICE_REMOVED, event.virtualDevice()));
+                    break;
+                case VIRTUAL_PORT_ADDED:
+                    post(new DeviceEvent(Type.PORT_ADDED, event.virtualDevice(), event.virtualPort()));
+                    break;
+                case VIRTUAL_PORT_UPDATED:
+                    post(new DeviceEvent(Type.PORT_UPDATED, event.virtualDevice(), event.virtualPort()));
+                    break;
+                case VIRTUAL_PORT_REMOVED:
+                    post(new DeviceEvent(Type.PORT_REMOVED, event.virtualDevice(), event.virtualPort()));
+                    break;
+                case NETWORK_UPDATED:
+                case NETWORK_REMOVED:
+                case NETWORK_ADDED:
+                default:
+                    // do nothing
+                    break;
+            }
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManager.java
new file mode 100644
index 0000000..c4e2031
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManager.java
@@ -0,0 +1,716 @@
+/*
+ * Copyright 2018-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.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.RemovalCause;
+import com.google.common.cache.RemovalNotification;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.incubator.net.virtual.AbstractVnetService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.NextGroup;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.behaviour.PipelinerContext;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.FlowObjectiveStore;
+import org.onosproject.net.flowobjective.FlowObjectiveStoreDelegate;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.flowobjective.ObjectiveEvent;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.GroupKey;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.BoundedThreadPool.newFixedThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Provides implementation of the flow objective programming service for virtual networks.
+ */
+// NOTE: This manager is designed to provide flow objective programming service
+// for virtual networks. Actually, virtual networks don't need to consider
+// the different implementation of data-path pipeline. But, the interfaces
+// and usages of flow objective service are still valuable for virtual network.
+// This manager is working as an interpreter from FlowObjective to FlowRules
+// to provide symmetric interfaces with ONOS core services.
+// The behaviours are based on DefaultSingleTablePipeline.
+
+public class VirtualNetworkFlowObjectiveManager extends AbstractVnetService
+        implements FlowObjectiveService {
+
+    public static final int INSTALL_RETRY_ATTEMPTS = 5;
+    public static final long INSTALL_RETRY_INTERVAL = 1000; // ms
+
+    private final Logger log = getLogger(getClass());
+
+    protected DeviceService deviceService;
+
+    // Note: The following dependencies are added on behalf of the pipeline
+    // driver behaviours to assure these services are available for their
+    // initialization.
+    protected FlowRuleService flowRuleService;
+
+    protected VirtualNetworkFlowObjectiveStore virtualFlowObjectiveStore;
+    protected FlowObjectiveStore flowObjectiveStore;
+    private final FlowObjectiveStoreDelegate delegate;
+
+    private final PipelinerContext context = new InnerPipelineContext();
+
+    private final Map<DeviceId, Pipeliner> pipeliners = Maps.newConcurrentMap();
+
+    // local stores for queuing fwd and next objectives that are waiting for an
+    // associated next objective execution to complete. The signal for completed
+    // execution comes from a pipeline driver, in this or another controller
+    // instance, via the DistributedFlowObjectiveStore.
+    private final Map<Integer, Set<PendingFlowObjective>> pendingForwards =
+            Maps.newConcurrentMap();
+    private final Map<Integer, Set<PendingFlowObjective>> pendingNexts =
+            Maps.newConcurrentMap();
+
+    // local store to track which nextObjectives were sent to which device
+    // for debugging purposes
+    private Map<Integer, DeviceId> nextToDevice = Maps.newConcurrentMap();
+
+    private ExecutorService executorService;
+
+    public VirtualNetworkFlowObjectiveManager(VirtualNetworkService manager,
+                                              NetworkId networkId) {
+        super(manager, networkId);
+
+        deviceService = manager.get(networkId(), DeviceService.class);
+        flowRuleService = manager.get(networkId(), FlowRuleService.class);
+
+        executorService = newFixedThreadPool(4, groupedThreads("onos/virtual/objective-installer", "%d", log));
+
+        virtualFlowObjectiveStore =
+                serviceDirectory.get(VirtualNetworkFlowObjectiveStore.class);
+        delegate = new InternalStoreDelegate();
+        virtualFlowObjectiveStore.setDelegate(networkId(), delegate);
+        flowObjectiveStore = new StoreConvertor();
+    }
+
+    @Override
+    public void filter(DeviceId deviceId, FilteringObjective filteringObjective) {
+        executorService.execute(new ObjectiveInstaller(deviceId, filteringObjective));
+    }
+
+    @Override
+    public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
+        if (forwardingObjective.nextId() == null ||
+                forwardingObjective.op() == Objective.Operation.REMOVE ||
+                flowObjectiveStore.getNextGroup(forwardingObjective.nextId()) != null ||
+                !queueFwdObjective(deviceId, forwardingObjective)) {
+            // fast path
+            executorService.execute(new ObjectiveInstaller(deviceId, forwardingObjective));
+        }
+    }
+
+    @Override
+    public void next(DeviceId deviceId, NextObjective nextObjective) {
+        nextToDevice.put(nextObjective.id(), deviceId);
+        if (nextObjective.op() == Objective.Operation.ADD ||
+                flowObjectiveStore.getNextGroup(nextObjective.id()) != null ||
+                !queueNextObjective(deviceId, nextObjective)) {
+            // either group exists or we are trying to create it - let it through
+            executorService.execute(new ObjectiveInstaller(deviceId, nextObjective));
+        }
+    }
+
+    @Override
+    public int allocateNextId() {
+        return flowObjectiveStore.allocateNextId();
+    }
+
+    @Override
+    public void initPolicy(String policy) {
+
+    }
+
+    @Override
+    public List<String> getNextMappings() {
+        List<String> mappings = new ArrayList<>();
+        Map<Integer, NextGroup> allnexts = flowObjectiveStore.getAllGroups();
+        // XXX if the NextGroup after de-serialization actually stored info of the deviceId
+        // then info on any nextObj could be retrieved from one controller instance.
+        // Right now the drivers on one instance can only fetch for next-ids that came
+        // to them.
+        // Also, we still need to send the right next-id to the right driver as potentially
+        // there can be different drivers for different devices. But on that account,
+        // no instance should be decoding for another instance's nextIds.
+
+        for (Map.Entry<Integer, NextGroup> e : allnexts.entrySet()) {
+            // get the device this next Objective was sent to
+            DeviceId deviceId = nextToDevice.get(e.getKey());
+            mappings.add("NextId " + e.getKey() + ": " +
+                                 ((deviceId != null) ? deviceId : "nextId not in this onos instance"));
+            if (deviceId != null) {
+                // this instance of the controller sent the nextObj to a driver
+                Pipeliner pipeliner = getDevicePipeliner(deviceId);
+                List<String> nextMappings = pipeliner.getNextMappings(e.getValue());
+                if (nextMappings != null) {
+                    mappings.addAll(nextMappings);
+                }
+            }
+        }
+        return mappings;
+    }
+
+    @Override
+    public List<String> getPendingFlowObjectives() {
+        List<String> pendingFlowObjectives = new ArrayList<>();
+
+        for (Integer nextId : pendingForwards.keySet()) {
+            Set<PendingFlowObjective> pfwd = pendingForwards.get(nextId);
+            StringBuilder pend = new StringBuilder();
+            pend.append("NextId: ")
+                    .append(nextId);
+            for (PendingFlowObjective pf : pfwd) {
+                pend.append("\n    FwdId: ")
+                        .append(String.format("%11s", pf.flowObjective().id()))
+                        .append(", DeviceId: ")
+                        .append(pf.deviceId())
+                        .append(", Selector: ")
+                        .append(((ForwardingObjective) pf.flowObjective())
+                                        .selector().criteria());
+            }
+            pendingFlowObjectives.add(pend.toString());
+        }
+
+        for (Integer nextId : pendingNexts.keySet()) {
+            Set<PendingFlowObjective> pnext = pendingNexts.get(nextId);
+            StringBuilder pend = new StringBuilder();
+            pend.append("NextId: ")
+                    .append(nextId);
+            for (PendingFlowObjective pn : pnext) {
+                pend.append("\n    NextOp: ")
+                        .append(pn.flowObjective().op())
+                        .append(", DeviceId: ")
+                        .append(pn.deviceId())
+                        .append(", Treatments: ")
+                        .append(((NextObjective) pn.flowObjective())
+                                        .next());
+            }
+            pendingFlowObjectives.add(pend.toString());
+        }
+
+        return pendingFlowObjectives;
+    }
+
+    private boolean queueFwdObjective(DeviceId deviceId, ForwardingObjective fwd) {
+        boolean queued = false;
+        synchronized (pendingForwards) {
+            // double check the flow objective store, because this block could run
+            // after a notification arrives
+            if (flowObjectiveStore.getNextGroup(fwd.nextId()) == null) {
+                pendingForwards.compute(fwd.nextId(), (id, pending) -> {
+                    PendingFlowObjective pendfo = new PendingFlowObjective(deviceId, fwd);
+                    if (pending == null) {
+                        return Sets.newHashSet(pendfo);
+                    } else {
+                        pending.add(pendfo);
+                        return pending;
+                    }
+                });
+                queued = true;
+            }
+        }
+        if (queued) {
+            log.debug("Queued forwarding objective {} for nextId {} meant for device {}",
+                      fwd.id(), fwd.nextId(), deviceId);
+        }
+        return queued;
+    }
+
+    private boolean queueNextObjective(DeviceId deviceId, NextObjective next) {
+
+        // we need to hold off on other operations till we get notified that the
+        // initial group creation has succeeded
+        boolean queued = false;
+        synchronized (pendingNexts) {
+            // double check the flow objective store, because this block could run
+            // after a notification arrives
+            if (flowObjectiveStore.getNextGroup(next.id()) == null) {
+                pendingNexts.compute(next.id(), (id, pending) -> {
+                    PendingFlowObjective pendfo = new PendingFlowObjective(deviceId, next);
+                    if (pending == null) {
+                        return Sets.newHashSet(pendfo);
+                    } else {
+                        pending.add(pendfo);
+                        return pending;
+                    }
+                });
+                queued = true;
+            }
+        }
+        if (queued) {
+            log.debug("Queued next objective {} with operation {} meant for device {}",
+                      next.id(), next.op(), deviceId);
+        }
+        return queued;
+    }
+
+    /**
+     * Task that passes the flow objective down to the driver. The task will
+     * make a few attempts to find the appropriate driver, then eventually give
+     * up and report an error if no suitable driver could be found.
+     */
+    private class ObjectiveInstaller implements Runnable {
+        private final DeviceId deviceId;
+        private final Objective objective;
+
+        private final int numAttempts;
+
+        public ObjectiveInstaller(DeviceId deviceId, Objective objective) {
+            this(deviceId, objective, 1);
+        }
+
+        public ObjectiveInstaller(DeviceId deviceId, Objective objective, int attemps) {
+            this.deviceId = checkNotNull(deviceId);
+            this.objective = checkNotNull(objective);
+            this.numAttempts = attemps;
+        }
+
+        @Override
+        public void run() {
+            try {
+                Pipeliner pipeliner = getDevicePipeliner(deviceId);
+
+                if (pipeliner != null) {
+                    if (objective instanceof NextObjective) {
+                        nextToDevice.put(objective.id(), deviceId);
+                        pipeliner.next((NextObjective) objective);
+                    } else if (objective instanceof ForwardingObjective) {
+                        pipeliner.forward((ForwardingObjective) objective);
+                    } else {
+                        pipeliner.filter((FilteringObjective) objective);
+                    }
+                    //Attempts to check if pipeliner is null for retry attempts
+                } else if (numAttempts < INSTALL_RETRY_ATTEMPTS) {
+                    Thread.sleep(INSTALL_RETRY_INTERVAL);
+                    executorService.execute(new ObjectiveInstaller(deviceId, objective, numAttempts + 1));
+                } else {
+                    // Otherwise we've tried a few times and failed, report an
+                    // error back to the user.
+                    objective.context().ifPresent(
+                            c -> c.onError(objective, ObjectiveError.NOPIPELINER));
+                }
+                //Exception thrown
+            } catch (Exception e) {
+                log.warn("Exception while installing flow objective", e);
+            }
+        }
+    }
+
+    private class InternalStoreDelegate implements FlowObjectiveStoreDelegate {
+        @Override
+        public void notify(ObjectiveEvent event) {
+            if (event.type() == ObjectiveEvent.Type.ADD) {
+                log.debug("Received notification of obj event {}", event);
+                Set<PendingFlowObjective> pending;
+
+                // first send all pending flows
+                synchronized (pendingForwards) {
+                    // needs to be synchronized for queueObjective lookup
+                    pending = pendingForwards.remove(event.subject());
+                }
+                if (pending == null) {
+                    log.debug("No forwarding objectives pending for this "
+                                      + "obj event {}", event);
+                } else {
+                    log.debug("Processing {} pending forwarding objectives for nextId {}",
+                              pending.size(), event.subject());
+                    pending.forEach(p -> getDevicePipeliner(p.deviceId())
+                            .forward((ForwardingObjective) p.flowObjective()));
+                }
+
+                // now check for pending next-objectives
+                synchronized (pendingNexts) {
+                    // needs to be synchronized for queueObjective lookup
+                    pending = pendingNexts.remove(event.subject());
+                }
+                if (pending == null) {
+                    log.debug("No next objectives pending for this "
+                                      + "obj event {}", event);
+                } else {
+                    log.debug("Processing {} pending next objectives for nextId {}",
+                              pending.size(), event.subject());
+                    pending.forEach(p -> getDevicePipeliner(p.deviceId())
+                            .next((NextObjective) p.flowObjective()));
+                }
+            }
+        }
+    }
+
+    /**
+     * Retrieves (if it exists) the device pipeline behaviour from the cache.
+     * Otherwise it warms the caches and triggers the init method of the Pipeline.
+     * For virtual network, it returns OVS pipeliner.
+     *
+     * @param deviceId the id of the device associated to the pipeline
+     * @return the implementation of the Pipeliner behaviour
+     */
+    private Pipeliner getDevicePipeliner(DeviceId deviceId) {
+        return pipeliners.computeIfAbsent(deviceId, this::initPipelineHandler);
+    }
+
+    /**
+     * Creates and initialize {@link Pipeliner}.
+     * <p>
+     * Note: Expected to be called under per-Device lock.
+     *      e.g., {@code pipeliners}' Map#compute family methods
+     *
+     * @param deviceId Device to initialize pipeliner
+     * @return {@link Pipeliner} instance or null
+     */
+    private Pipeliner initPipelineHandler(DeviceId deviceId) {
+        //FIXME: do we need a standard pipeline for virtual device?
+        Pipeliner pipeliner = new DefaultVirtualDevicePipeline();
+        pipeliner.init(deviceId, context);
+        return pipeliner;
+    }
+
+    // Processing context for initializing pipeline driver behaviours.
+    private class InnerPipelineContext implements PipelinerContext {
+        @Override
+        public ServiceDirectory directory() {
+            return serviceDirectory;
+        }
+
+        @Override
+        public FlowObjectiveStore store() {
+            return flowObjectiveStore;
+        }
+    }
+
+    /**
+     * Data class used to hold a pending flow objective that could not
+     * be processed because the associated next object was not present.
+     * Note that this pending flow objective could be a forwarding objective
+     * waiting for a next objective to complete execution. Or it could a
+     * next objective (with a different operation - remove, addToExisting, or
+     * removeFromExisting) waiting for a next objective with the same id to
+     * complete execution.
+     */
+    private class PendingFlowObjective {
+        private final DeviceId deviceId;
+        private final Objective flowObj;
+
+        public PendingFlowObjective(DeviceId deviceId, Objective flowObj) {
+            this.deviceId = deviceId;
+            this.flowObj = flowObj;
+        }
+
+        public DeviceId deviceId() {
+            return deviceId;
+        }
+
+        public Objective flowObjective() {
+            return flowObj;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(deviceId, flowObj);
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (!(obj instanceof PendingFlowObjective)) {
+                return false;
+            }
+            final PendingFlowObjective other = (PendingFlowObjective) obj;
+            if (this.deviceId.equals(other.deviceId) &&
+                    this.flowObj.equals(other.flowObj)) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * This class is a wrapping class from VirtualNetworkFlowObjectiveStore
+     * to FlowObjectiveStore for PipelinerContext.
+     */
+    private class StoreConvertor implements FlowObjectiveStore {
+
+        @Override
+        public void setDelegate(FlowObjectiveStoreDelegate delegate) {
+            virtualFlowObjectiveStore.setDelegate(networkId(), delegate);
+        }
+
+        @Override
+        public void unsetDelegate(FlowObjectiveStoreDelegate delegate) {
+            virtualFlowObjectiveStore.unsetDelegate(networkId(), delegate);
+        }
+
+        @Override
+        public boolean hasDelegate() {
+            return virtualFlowObjectiveStore.hasDelegate(networkId());
+        }
+
+        @Override
+        public void putNextGroup(Integer nextId, NextGroup group) {
+            virtualFlowObjectiveStore.putNextGroup(networkId(), nextId, group);
+        }
+
+        @Override
+        public NextGroup getNextGroup(Integer nextId) {
+            return virtualFlowObjectiveStore.getNextGroup(networkId(), nextId);
+        }
+
+        @Override
+        public NextGroup removeNextGroup(Integer nextId) {
+            return virtualFlowObjectiveStore.removeNextGroup(networkId(), nextId);
+        }
+
+        @Override
+        public Map<Integer, NextGroup> getAllGroups() {
+            return virtualFlowObjectiveStore.getAllGroups(networkId());
+        }
+
+        @Override
+        public int allocateNextId() {
+            return virtualFlowObjectiveStore.allocateNextId(networkId());
+        }
+    }
+
+    /**
+     * Simple single table pipeline abstraction for virtual networks.
+     */
+    private class DefaultVirtualDevicePipeline
+            extends AbstractHandlerBehaviour implements Pipeliner {
+
+        private final Logger log = getLogger(getClass());
+
+        private DeviceId deviceId;
+
+        private Cache<Integer, NextObjective> pendingNext;
+
+        private KryoNamespace appKryo = new KryoNamespace.Builder()
+                .register(GroupKey.class)
+                .register(DefaultGroupKey.class)
+                .register(SingleGroup.class)
+                .register(byte[].class)
+                .build("DefaultVirtualDevicePipeline");
+
+        @Override
+        public void init(DeviceId deviceId, PipelinerContext context) {
+            this.deviceId = deviceId;
+
+            pendingNext = CacheBuilder.newBuilder()
+                    .expireAfterWrite(20, TimeUnit.SECONDS)
+                    .removalListener((RemovalNotification<Integer, NextObjective> notification) -> {
+                        if (notification.getCause() == RemovalCause.EXPIRED) {
+                            notification.getValue().context()
+                                    .ifPresent(c -> c.onError(notification.getValue(),
+                                                              ObjectiveError.FLOWINSTALLATIONFAILED));
+                        }
+                    }).build();
+        }
+
+        @Override
+        public void filter(FilteringObjective filter) {
+
+            TrafficTreatment.Builder actions;
+            switch (filter.type()) {
+                case PERMIT:
+                    actions = (filter.meta() == null) ?
+                            DefaultTrafficTreatment.builder().punt() :
+                            DefaultTrafficTreatment.builder(filter.meta());
+                    break;
+                case DENY:
+                    actions = (filter.meta() == null) ?
+                            DefaultTrafficTreatment.builder() :
+                            DefaultTrafficTreatment.builder(filter.meta());
+                    actions.drop();
+                    break;
+                default:
+                    log.warn("Unknown filter type: {}", filter.type());
+                    actions = DefaultTrafficTreatment.builder().drop();
+            }
+
+            TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+            filter.conditions().forEach(selector::add);
+
+            if (filter.key() != null) {
+                selector.add(filter.key());
+            }
+
+            FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+                    .forDevice(deviceId)
+                    .withSelector(selector.build())
+                    .withTreatment(actions.build())
+                    .fromApp(filter.appId())
+                    .withPriority(filter.priority());
+
+            if (filter.permanent()) {
+                ruleBuilder.makePermanent();
+            } else {
+                ruleBuilder.makeTemporary(filter.timeout());
+            }
+
+            installObjective(ruleBuilder, filter);
+        }
+
+        @Override
+        public void forward(ForwardingObjective fwd) {
+            TrafficSelector selector = fwd.selector();
+
+            if (fwd.treatment() != null) {
+                // Deal with SPECIFIC and VERSATILE in the same manner.
+                FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+                        .forDevice(deviceId)
+                        .withSelector(selector)
+                        .fromApp(fwd.appId())
+                        .withPriority(fwd.priority())
+                        .withTreatment(fwd.treatment());
+
+                if (fwd.permanent()) {
+                    ruleBuilder.makePermanent();
+                } else {
+                    ruleBuilder.makeTemporary(fwd.timeout());
+                }
+                installObjective(ruleBuilder, fwd);
+
+            } else {
+                NextObjective nextObjective = pendingNext.getIfPresent(fwd.nextId());
+                if (nextObjective != null) {
+                    pendingNext.invalidate(fwd.nextId());
+                    nextObjective.next().forEach(treat -> {
+                        FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+                                .forDevice(deviceId)
+                                .withSelector(selector)
+                                .fromApp(fwd.appId())
+                                .withPriority(fwd.priority())
+                                .withTreatment(treat);
+
+                        if (fwd.permanent()) {
+                            ruleBuilder.makePermanent();
+                        } else {
+                            ruleBuilder.makeTemporary(fwd.timeout());
+                        }
+                        installObjective(ruleBuilder, fwd);
+                    });
+                } else {
+                    fwd.context().ifPresent(c -> c.onError(fwd,
+                                                           ObjectiveError.GROUPMISSING));
+                }
+            }
+        }
+
+        private void installObjective(FlowRule.Builder ruleBuilder, Objective objective) {
+            FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
+            switch (objective.op()) {
+
+                case ADD:
+                    flowBuilder.add(ruleBuilder.build());
+                    break;
+                case REMOVE:
+                    flowBuilder.remove(ruleBuilder.build());
+                    break;
+                default:
+                    log.warn("Unknown operation {}", objective.op());
+            }
+
+            flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
+                @Override
+                public void onSuccess(FlowRuleOperations ops) {
+                    objective.context().ifPresent(context -> context.onSuccess(objective));
+                }
+
+                @Override
+                public void onError(FlowRuleOperations ops) {
+                    objective.context()
+                            .ifPresent(context ->
+                                               context.onError(objective,
+                                                                  ObjectiveError.FLOWINSTALLATIONFAILED));
+                }
+            }));
+        }
+
+        @Override
+        public void next(NextObjective nextObjective) {
+
+            pendingNext.put(nextObjective.id(), nextObjective);
+            flowObjectiveStore.putNextGroup(nextObjective.id(),
+                                            new SingleGroup(
+                                                    new DefaultGroupKey(
+                                                            appKryo.serialize(nextObjective.id()))));
+            nextObjective.context().ifPresent(context -> context.onSuccess(nextObjective));
+        }
+
+        @Override
+        public List<String> getNextMappings(NextGroup nextGroup) {
+            // Default single table pipeline does not use nextObjectives or groups
+            return null;
+        }
+
+        private class SingleGroup implements NextGroup {
+
+            private final GroupKey key;
+
+            public SingleGroup(GroupKey key) {
+                this.key = key;
+            }
+
+            public GroupKey key() {
+                return key;
+            }
+
+            @Override
+            public byte[] data() {
+                return appKryo.serialize(key);
+            }
+        }
+    }
+
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManager.java
new file mode 100644
index 0000000..f501696
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManager.java
@@ -0,0 +1,574 @@
+/*
+ * Copyright 2018-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.ArrayListMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+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.oldbatch.FlowRuleBatchEntry;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchEvent;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchRequest;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleListener;
+import org.onosproject.net.flow.FlowRuleOperation;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.FlowRuleStoreDelegate;
+import org.onosproject.net.flow.TableStatisticsEntry;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_ADD_REQUESTED;
+import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_REMOVE_REQUESTED;
+
+/**
+ * Flow rule service implementation built on the virtual network service.
+ */
+public class VirtualNetworkFlowRuleManager
+        extends AbstractVirtualListenerManager<FlowRuleEvent, FlowRuleListener>
+        implements FlowRuleService {
+
+    private static final String VIRTUAL_FLOW_OP_TOPIC = "virtual-flow-ops-ids";
+    private static final String THREAD_GROUP_NAME = "onos/virtual-flowservice";
+    private static final String DEVICE_INSTALLER_PATTERN = "device-installer-%d";
+    private static final String OPERATION_PATTERN = "operations-%d";
+    public static final String FLOW_RULE_NULL = "FlowRule cannot be null";
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private final VirtualNetworkFlowRuleStore store;
+    private final DeviceService deviceService;
+
+    protected ExecutorService deviceInstallers =
+            Executors.newFixedThreadPool(32,
+                                         groupedThreads(THREAD_GROUP_NAME,
+                                                        DEVICE_INSTALLER_PATTERN, log));
+    protected ExecutorService operationsService =
+            Executors.newFixedThreadPool(32,
+                                         groupedThreads(THREAD_GROUP_NAME,
+                                                        OPERATION_PATTERN, log));
+    private IdGenerator idGenerator;
+
+    private final Map<Long, FlowOperationsProcessor> pendingFlowOperations = new ConcurrentHashMap<>();
+
+    private VirtualProviderRegistryService providerRegistryService = null;
+    private InternalFlowRuleProviderService innerProviderService = null;
+
+    private final FlowRuleStoreDelegate storeDelegate;
+
+    /**
+     * Creates a new VirtualNetworkFlowRuleService object.
+     *
+     * @param virtualNetworkManager virtual network manager service
+     * @param networkId a virtual network identifier
+     */
+    public VirtualNetworkFlowRuleManager(VirtualNetworkService virtualNetworkManager,
+                                         NetworkId networkId) {
+        super(virtualNetworkManager, networkId, FlowRuleEvent.class);
+
+        store = serviceDirectory.get(VirtualNetworkFlowRuleStore.class);
+
+        idGenerator = serviceDirectory.get(CoreService.class)
+                .getIdGenerator(VIRTUAL_FLOW_OP_TOPIC + networkId().toString());
+        providerRegistryService =
+                serviceDirectory.get(VirtualProviderRegistryService.class);
+        innerProviderService = new InternalFlowRuleProviderService();
+        providerRegistryService.registerProviderService(networkId(), innerProviderService);
+
+        this.deviceService = manager.get(networkId, DeviceService.class);
+        this.storeDelegate = new InternalStoreDelegate();
+        store.setDelegate(networkId, this.storeDelegate);
+    }
+
+    @Override
+    public int getFlowRuleCount() {
+        return store.getFlowRuleCount(networkId());
+    }
+
+    @Override
+    public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
+        return store.getFlowEntries(networkId(), deviceId);
+    }
+
+    @Override
+    public void applyFlowRules(FlowRule... flowRules) {
+        FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+        for (FlowRule flowRule : flowRules) {
+            builder.add(flowRule);
+        }
+        apply(builder.build());
+    }
+
+    @Override
+    public void purgeFlowRules(DeviceId deviceId) {
+        store.purgeFlowRule(networkId(), deviceId);
+    }
+
+    @Override
+    public void removeFlowRules(FlowRule... flowRules) {
+        FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+        for (FlowRule flowRule : flowRules) {
+            builder.remove(flowRule);
+        }
+        apply(builder.build());
+    }
+
+    @Override
+    public void removeFlowRulesById(ApplicationId id) {
+        removeFlowRules(Iterables.toArray(getFlowRulesById(id), FlowRule.class));
+    }
+
+    @Override
+    public Iterable<FlowRule> getFlowRulesById(ApplicationId id) {
+        DeviceService deviceService = manager.get(networkId(), DeviceService.class);
+
+        Set<FlowRule> flowEntries = Sets.newHashSet();
+        for (Device d : deviceService.getDevices()) {
+            for (FlowEntry flowEntry : store.getFlowEntries(networkId(), d.id())) {
+                if (flowEntry.appId() == id.id()) {
+                    flowEntries.add(flowEntry);
+                }
+            }
+        }
+        return flowEntries;
+    }
+
+    @Override
+    public Iterable<FlowEntry> getFlowEntriesById(ApplicationId id) {
+        DeviceService deviceService = manager.get(networkId(), DeviceService.class);
+
+        Set<FlowEntry> flowEntries = Sets.newHashSet();
+        for (Device d : deviceService.getDevices()) {
+            for (FlowEntry flowEntry : store.getFlowEntries(networkId(), d.id())) {
+                if (flowEntry.appId() == id.id()) {
+                    flowEntries.add(flowEntry);
+                }
+            }
+        }
+        return flowEntries;
+    }
+
+    @Override
+    public Iterable<FlowRule> getFlowRulesByGroupId(ApplicationId appId, short groupId) {
+        DeviceService deviceService = manager.get(networkId(), DeviceService.class);
+
+        Set<FlowRule> matches = Sets.newHashSet();
+        long toLookUp = ((long) appId.id() << 16) | groupId;
+        for (Device d : deviceService.getDevices()) {
+            for (FlowEntry flowEntry : store.getFlowEntries(networkId(), d.id())) {
+                if ((flowEntry.id().value() >>> 32) == toLookUp) {
+                    matches.add(flowEntry);
+                }
+            }
+        }
+        return matches;
+    }
+
+    @Override
+    public void apply(FlowRuleOperations ops) {
+        operationsService.execute(new FlowOperationsProcessor(ops));
+    }
+
+    @Override
+    public Iterable<TableStatisticsEntry> getFlowTableStatistics(DeviceId deviceId) {
+        return store.getTableStatistics(networkId(), deviceId);
+    }
+
+    private static FlowRuleBatchEntry.FlowRuleOperation mapOperationType(FlowRuleOperation.Type input) {
+        switch (input) {
+            case ADD:
+                return FlowRuleBatchEntry.FlowRuleOperation.ADD;
+            case MODIFY:
+                return FlowRuleBatchEntry.FlowRuleOperation.MODIFY;
+            case REMOVE:
+                return FlowRuleBatchEntry.FlowRuleOperation.REMOVE;
+            default:
+                throw new UnsupportedOperationException("Unknown flow rule type " + input);
+        }
+    }
+
+    private class FlowOperationsProcessor implements Runnable {
+        // Immutable
+        private final FlowRuleOperations fops;
+
+        // Mutable
+        private final List<Set<FlowRuleOperation>> stages;
+        private final Set<DeviceId> pendingDevices = new HashSet<>();
+        private boolean hasFailed = false;
+
+        FlowOperationsProcessor(FlowRuleOperations ops) {
+            this.stages = Lists.newArrayList(ops.stages());
+            this.fops = ops;
+        }
+
+        @Override
+        public synchronized void run() {
+            if (!stages.isEmpty()) {
+                process(stages.remove(0));
+            } else if (!hasFailed) {
+                fops.callback().onSuccess(fops);
+            }
+        }
+
+        private void process(Set<FlowRuleOperation> ops) {
+            Multimap<DeviceId, FlowRuleBatchEntry> perDeviceBatches = ArrayListMultimap.create();
+
+            for (FlowRuleOperation op : ops) {
+                perDeviceBatches.put(op.rule().deviceId(),
+                                     new FlowRuleBatchEntry(mapOperationType(op.type()), op.rule()));
+            }
+            pendingDevices.addAll(perDeviceBatches.keySet());
+
+            for (DeviceId deviceId : perDeviceBatches.keySet()) {
+                long id = idGenerator.getNewId();
+                final FlowRuleBatchOperation b = new FlowRuleBatchOperation(perDeviceBatches.get(deviceId),
+                                                                            deviceId, id);
+                pendingFlowOperations.put(id, this);
+                deviceInstallers.execute(() -> store.storeBatch(networkId(), b));
+            }
+        }
+
+        synchronized void satisfy(DeviceId devId) {
+            pendingDevices.remove(devId);
+            if (pendingDevices.isEmpty()) {
+                operationsService.execute(this);
+            }
+        }
+
+        synchronized void fail(DeviceId devId, Set<? extends FlowRule> failures) {
+            hasFailed = true;
+            pendingDevices.remove(devId);
+            if (pendingDevices.isEmpty()) {
+                operationsService.execute(this);
+            }
+
+            FlowRuleOperations.Builder failedOpsBuilder = FlowRuleOperations.builder();
+            failures.forEach(failedOpsBuilder::add);
+
+            fops.callback().onError(failedOpsBuilder.build());
+        }
+    }
+
+    private final class InternalFlowRuleProviderService
+            extends AbstractVirtualProviderService<VirtualFlowRuleProvider>
+            implements VirtualFlowRuleProviderService {
+
+        final Map<FlowEntry, Long> firstSeen = Maps.newConcurrentMap();
+        final Map<FlowEntry, Long> lastSeen = Maps.newConcurrentMap();
+
+        private InternalFlowRuleProviderService() {
+            //TODO: find a proper virtual provider.
+            Set<ProviderId> providerIds =
+                    providerRegistryService.getProvidersByService(this);
+            ProviderId providerId = providerIds.stream().findFirst().get();
+            VirtualFlowRuleProvider provider = (VirtualFlowRuleProvider)
+                    providerRegistryService.getProvider(providerId);
+            setProvider(provider);
+        }
+
+        @Override
+        public void flowRemoved(FlowEntry flowEntry) {
+            checkNotNull(flowEntry, FLOW_RULE_NULL);
+            checkValidity();
+
+            lastSeen.remove(flowEntry);
+            firstSeen.remove(flowEntry);
+            FlowEntry stored = store.getFlowEntry(networkId(), flowEntry);
+            if (stored == null) {
+                log.debug("Rule already evicted from store: {}", flowEntry);
+                return;
+            }
+            if (flowEntry.reason() == FlowEntry.FlowRemoveReason.HARD_TIMEOUT) {
+                ((DefaultFlowEntry) stored).setState(FlowEntry.FlowEntryState.REMOVED);
+            }
+
+            //FIXME: obtains provider from devices providerId()
+            FlowRuleEvent event = null;
+            switch (stored.state()) {
+                case ADDED:
+                case PENDING_ADD:
+                    provider().applyFlowRule(networkId(), stored);
+                    break;
+                case PENDING_REMOVE:
+                case REMOVED:
+                    event = store.removeFlowRule(networkId(), stored);
+                    break;
+                default:
+                    break;
+
+            }
+            if (event != null) {
+                log.debug("Flow {} removed", flowEntry);
+                post(event);
+            }
+        }
+
+        private void flowMissing(FlowEntry flowRule) {
+            checkNotNull(flowRule, FLOW_RULE_NULL);
+            checkValidity();
+
+            FlowRuleEvent event = null;
+            switch (flowRule.state()) {
+                case PENDING_REMOVE:
+                case REMOVED:
+                    event = store.removeFlowRule(networkId(), flowRule);
+                    break;
+                case ADDED:
+                case PENDING_ADD:
+                    event = store.pendingFlowRule(networkId(), flowRule);
+
+                    try {
+                        provider().applyFlowRule(networkId(), flowRule);
+                    } catch (UnsupportedOperationException e) {
+                        log.warn(e.getMessage());
+                        if (flowRule instanceof DefaultFlowEntry) {
+                            //FIXME modification of "stored" flow entry outside of store
+                            ((DefaultFlowEntry) flowRule).setState(FlowEntry.FlowEntryState.FAILED);
+                        }
+                    }
+                    break;
+                default:
+                    log.debug("Flow {} has not been installed.", flowRule);
+            }
+
+            if (event != null) {
+                log.debug("Flow {} removed", flowRule);
+                post(event);
+            }
+        }
+
+        private void extraneousFlow(FlowRule flowRule) {
+            checkNotNull(flowRule, FLOW_RULE_NULL);
+            checkValidity();
+
+            provider().removeFlowRule(networkId(), flowRule);
+            log.debug("Flow {} is on switch but not in store.", flowRule);
+        }
+
+        private void flowAdded(FlowEntry flowEntry) {
+            checkNotNull(flowEntry, FLOW_RULE_NULL);
+
+            if (checkRuleLiveness(flowEntry, store.getFlowEntry(networkId(), flowEntry))) {
+                FlowRuleEvent event = store.addOrUpdateFlowRule(networkId(), flowEntry);
+                if (event == null) {
+                    log.debug("No flow store event generated.");
+                } else {
+                    log.trace("Flow {} {}", flowEntry, event.type());
+                    post(event);
+                }
+            } else {
+                log.debug("Removing flow rules....");
+                removeFlowRules(flowEntry);
+            }
+        }
+
+        private boolean checkRuleLiveness(FlowEntry swRule, FlowEntry storedRule) {
+            if (storedRule == null) {
+                return false;
+            }
+            if (storedRule.isPermanent()) {
+                return true;
+            }
+
+            final long timeout = storedRule.timeout() * 1000L;
+            final long currentTime = System.currentTimeMillis();
+
+            // Checking flow with hardTimeout
+            if (storedRule.hardTimeout() != 0) {
+                if (!firstSeen.containsKey(storedRule)) {
+                    // First time rule adding
+                    firstSeen.put(storedRule, currentTime);
+                } else {
+                    Long first = firstSeen.get(storedRule);
+                    final long hardTimeout = storedRule.hardTimeout() * 1000L;
+                    if ((currentTime - first) > hardTimeout) {
+                        return false;
+                    }
+                }
+            }
+
+            if (storedRule.packets() != swRule.packets()) {
+                lastSeen.put(storedRule, currentTime);
+                return true;
+            }
+            if (!lastSeen.containsKey(storedRule)) {
+                // checking for the first time
+                lastSeen.put(storedRule, storedRule.lastSeen());
+                // Use following if lastSeen attr. was removed.
+                //lastSeen.put(storedRule, currentTime);
+            }
+            Long last = lastSeen.get(storedRule);
+
+            // concurrently removed? let the liveness check fail
+            return last != null && (currentTime - last) <= timeout;
+        }
+
+        @Override
+        public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries) {
+            pushFlowMetricsInternal(deviceId, flowEntries, true);
+        }
+
+        @Override
+        public void pushFlowMetricsWithoutFlowMissing(DeviceId deviceId, Iterable<FlowEntry> flowEntries) {
+            pushFlowMetricsInternal(deviceId, flowEntries, false);
+        }
+
+        private void pushFlowMetricsInternal(DeviceId deviceId, Iterable<FlowEntry> flowEntries,
+                                             boolean useMissingFlow) {
+            Map<FlowEntry, FlowEntry> storedRules = Maps.newHashMap();
+            store.getFlowEntries(networkId(), deviceId).forEach(f -> storedRules.put(f, f));
+
+            for (FlowEntry rule : flowEntries) {
+                try {
+                    FlowEntry storedRule = storedRules.remove(rule);
+                    if (storedRule != null) {
+                        if (storedRule.id().equals(rule.id())) {
+                            // we both have the rule, let's update some info then.
+                            flowAdded(rule);
+                        } else {
+                            // the two rules are not an exact match - remove the
+                            // switch's rule and install our rule
+                            extraneousFlow(rule);
+                            flowMissing(storedRule);
+                        }
+                    }
+                } catch (Exception e) {
+                    log.debug("Can't process added or extra rule {}", e.getMessage());
+                }
+            }
+
+            // DO NOT reinstall
+            if (useMissingFlow) {
+                for (FlowEntry rule : storedRules.keySet()) {
+                    try {
+                        // there are rules in the store that aren't on the switch
+                        log.debug("Adding rule in store, but not on switch {}", rule);
+                        flowMissing(rule);
+                    } catch (Exception e) {
+                        log.debug("Can't add missing flow rule:", e);
+                    }
+                }
+            }
+        }
+
+        public void batchOperationCompleted(long batchId, CompletedBatchOperation operation) {
+            store.batchOperationComplete(networkId(), FlowRuleBatchEvent.completed(
+                    new FlowRuleBatchRequest(batchId, Collections.emptySet()),
+                    operation
+            ));
+        }
+
+        @Override
+        public void pushTableStatistics(DeviceId deviceId,
+                                        List<TableStatisticsEntry> tableStats) {
+            store.updateTableStatistics(networkId(), deviceId, tableStats);
+        }
+    }
+
+    // Store delegate to re-post events emitted from the store.
+    private class InternalStoreDelegate implements FlowRuleStoreDelegate {
+
+        // TODO: Right now we only dispatch events at individual flowEntry level.
+        // It may be more efficient for also dispatch events as a batch.
+        @Override
+        public void notify(FlowRuleBatchEvent event) {
+            final FlowRuleBatchRequest request = event.subject();
+            switch (event.type()) {
+                case BATCH_OPERATION_REQUESTED:
+                    // Request has been forwarded to MASTER Node, and was
+                    request.ops().forEach(
+                            op -> {
+                                switch (op.operator()) {
+                                    case ADD:
+                                        post(new FlowRuleEvent(RULE_ADD_REQUESTED, op.target()));
+                                        break;
+                                    case REMOVE:
+                                        post(new FlowRuleEvent(RULE_REMOVE_REQUESTED, op.target()));
+                                        break;
+                                    case MODIFY:
+                                        //TODO: do something here when the time comes.
+                                        break;
+                                    default:
+                                        log.warn("Unknown flow operation operator: {}", op.operator());
+                                }
+                            }
+                    );
+
+                    DeviceId deviceId = event.deviceId();
+                    FlowRuleBatchOperation batchOperation = request.asBatchOperation(deviceId);
+
+                    VirtualFlowRuleProvider provider = innerProviderService.provider();
+                    if (provider != null) {
+                        provider.executeBatch(networkId, batchOperation);
+                    }
+
+                    break;
+
+                case BATCH_OPERATION_COMPLETED:
+                    FlowOperationsProcessor fops = pendingFlowOperations.remove(
+                            event.subject().batchId());
+                    if (fops == null) {
+                       return;
+                    }
+
+                    if (event.result().isSuccess()) {
+                            fops.satisfy(event.deviceId());
+                    } else {
+                        fops.fail(event.deviceId(), event.result().failedItems());
+                    }
+                    break;
+
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkGroupManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkGroupManager.java
new file mode 100644
index 0000000..5fed4a8
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkGroupManager.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2018-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 org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkGroupStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualGroupProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualGroupProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupEvent;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupListener;
+import org.onosproject.net.group.GroupOperation;
+import org.onosproject.net.group.GroupOperations;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.group.GroupStoreDelegate;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Group service implementation built on the virtual network service.
+ */
+public class VirtualNetworkGroupManager
+        extends AbstractVirtualListenerManager<GroupEvent, GroupListener>
+        implements GroupService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private final VirtualNetworkGroupStore store;
+
+    private VirtualProviderRegistryService providerRegistryService = null;
+    private VirtualGroupProviderService innerProviderService;
+    private InternalStoreDelegate storeDelegate;
+    private DeviceService deviceService;
+
+    //TODO: make this configurable
+    private boolean purgeOnDisconnection = false;
+
+    public VirtualNetworkGroupManager(VirtualNetworkService manager, NetworkId networkId) {
+        super(manager, networkId, GroupEvent.class);
+
+        store = serviceDirectory.get(VirtualNetworkGroupStore.class);
+        deviceService = manager.get(networkId, DeviceService.class);
+
+        providerRegistryService =
+                serviceDirectory.get(VirtualProviderRegistryService.class);
+        innerProviderService = new InternalGroupProviderService();
+        providerRegistryService.registerProviderService(networkId(), innerProviderService);
+
+        this.storeDelegate = new InternalStoreDelegate();
+        store.setDelegate(networkId, this.storeDelegate);
+
+        log.info("Started");
+    }
+
+    @Override
+    public void addGroup(GroupDescription groupDesc) {
+        store.storeGroupDescription(networkId(), groupDesc);
+    }
+
+    @Override
+    public Group getGroup(DeviceId deviceId, GroupKey appCookie) {
+        return store.getGroup(networkId(), deviceId, appCookie);
+    }
+
+    @Override
+    public void addBucketsToGroup(DeviceId deviceId, GroupKey oldCookie, GroupBuckets buckets,
+                                  GroupKey newCookie, ApplicationId appId) {
+        store.updateGroupDescription(networkId(),
+                                     deviceId,
+                                     oldCookie,
+                                     VirtualNetworkGroupStore.UpdateType.ADD,
+                                     buckets,
+                                     newCookie);
+    }
+
+    @Override
+    public void removeBucketsFromGroup(DeviceId deviceId, GroupKey oldCookie,
+                                       GroupBuckets buckets, GroupKey newCookie,
+                                       ApplicationId appId) {
+        store.updateGroupDescription(networkId(),
+                                     deviceId,
+                                     oldCookie,
+                                     VirtualNetworkGroupStore.UpdateType.REMOVE,
+                                     buckets,
+                                     newCookie);
+
+    }
+
+    @Override
+    public void setBucketsForGroup(DeviceId deviceId,
+                                   GroupKey oldCookie,
+                                   GroupBuckets buckets,
+                                   GroupKey newCookie,
+                                   ApplicationId appId) {
+        store.updateGroupDescription(networkId(),
+                                     deviceId,
+                                     oldCookie,
+                                     VirtualNetworkGroupStore.UpdateType.SET,
+                                     buckets,
+                                     newCookie);
+    }
+
+    @Override
+    public void purgeGroupEntries(DeviceId deviceId) {
+        store.purgeGroupEntry(networkId(), deviceId);
+    }
+
+    @Override
+    public void purgeGroupEntries() {
+        store.purgeGroupEntries(networkId());
+    }
+
+    @Override
+    public void removeGroup(DeviceId deviceId, GroupKey appCookie, ApplicationId appId) {
+        store.deleteGroupDescription(networkId(), deviceId, appCookie);
+    }
+
+    @Override
+    public Iterable<Group> getGroups(DeviceId deviceId, ApplicationId appId) {
+        return store.getGroups(networkId(), deviceId);
+    }
+
+    @Override
+    public Iterable<Group> getGroups(DeviceId deviceId) {
+        return store.getGroups(networkId(), deviceId);
+    }
+
+    private class InternalGroupProviderService
+            extends AbstractVirtualProviderService<VirtualGroupProvider>
+            implements VirtualGroupProviderService {
+
+        protected InternalGroupProviderService() {
+            Set<ProviderId> providerIds =
+                    providerRegistryService.getProvidersByService(this);
+            ProviderId providerId = providerIds.stream().findFirst().get();
+            VirtualGroupProvider provider = (VirtualGroupProvider)
+                    providerRegistryService.getProvider(providerId);
+            setProvider(provider);
+        }
+
+        @Override
+        public void groupOperationFailed(DeviceId deviceId,
+                                         GroupOperation operation) {
+            store.groupOperationFailed(networkId(), deviceId, operation);
+        }
+
+        @Override
+        public void pushGroupMetrics(DeviceId deviceId, Collection<Group> groupEntries) {
+            log.trace("Received group metrics from device {}", deviceId);
+            checkValidity();
+            store.pushGroupMetrics(networkId(), deviceId, groupEntries);
+        }
+
+        @Override
+        public void notifyOfFailovers(Collection<Group> failoverGroups) {
+            store.notifyOfFailovers(networkId(), failoverGroups);
+        }
+    }
+
+    private class InternalStoreDelegate implements GroupStoreDelegate {
+        @Override
+        public void notify(GroupEvent event) {
+            final Group group = event.subject();
+            VirtualGroupProvider groupProvider = innerProviderService.provider();
+            GroupOperations groupOps = null;
+            switch (event.type()) {
+                case GROUP_ADD_REQUESTED:
+                    log.debug("GROUP_ADD_REQUESTED for Group {} on device {}",
+                              group.id(), group.deviceId());
+                    GroupOperation groupAddOp = GroupOperation.
+                            createAddGroupOperation(group.id(),
+                                                    group.type(),
+                                                    group.buckets());
+                    groupOps = new GroupOperations(
+                            Collections.singletonList(groupAddOp));
+                    groupProvider.performGroupOperation(networkId(), group.deviceId(),
+                                                        groupOps);
+                    break;
+
+                case GROUP_UPDATE_REQUESTED:
+                    log.debug("GROUP_UPDATE_REQUESTED for Group {} on device {}",
+                              group.id(), group.deviceId());
+                    GroupOperation groupModifyOp = GroupOperation.
+                            createModifyGroupOperation(group.id(),
+                                                       group.type(),
+                                                       group.buckets());
+                    groupOps = new GroupOperations(
+                            Collections.singletonList(groupModifyOp));
+                    groupProvider.performGroupOperation(networkId(), group.deviceId(),
+                                                        groupOps);
+                    break;
+
+                case GROUP_REMOVE_REQUESTED:
+                    log.debug("GROUP_REMOVE_REQUESTED for Group {} on device {}",
+                              group.id(), group.deviceId());
+                    GroupOperation groupDeleteOp = GroupOperation.
+                            createDeleteGroupOperation(group.id(),
+                                                       group.type());
+                    groupOps = new GroupOperations(
+                            Collections.singletonList(groupDeleteOp));
+                    groupProvider.performGroupOperation(networkId(), group.deviceId(),
+                                                        groupOps);
+                    break;
+
+                case GROUP_ADDED:
+                case GROUP_UPDATED:
+                case GROUP_REMOVED:
+                case GROUP_ADD_FAILED:
+                case GROUP_UPDATE_FAILED:
+                case GROUP_REMOVE_FAILED:
+                case GROUP_BUCKET_FAILOVER:
+                    post(event);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            switch (event.type()) {
+                case DEVICE_REMOVED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                    DeviceId deviceId = event.subject().id();
+                    if (!deviceService.isAvailable(deviceId)) {
+                        log.debug("Device {} became un available; clearing initial audit status",
+                                  event.type(), event.subject().id());
+                        store.deviceInitialAuditCompleted(networkId(), event.subject().id(), false);
+
+                        if (purgeOnDisconnection) {
+                            store.purgeGroupEntry(networkId(), deviceId);
+                        }
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManager.java
new file mode 100644
index 0000000..5d14d4a
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManager.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2018-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 org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Host service implementation built on the virtual network service.
+ */
+public class VirtualNetworkHostManager
+        extends AbstractVirtualListenerManager<HostEvent, HostListener>
+        implements HostService {
+
+    private static final String HOST_NULL = "Host ID cannot be null";
+
+    /**
+     * Creates a new virtual network host service object.
+     *
+     * @param virtualNetworkManager virtual network manager service
+     * @param networkId a virtual network identifier
+     */
+    public VirtualNetworkHostManager(VirtualNetworkService virtualNetworkManager,
+                                     NetworkId networkId) {
+        super(virtualNetworkManager, networkId, HostEvent.class);
+    }
+
+
+    @Override
+    public int getHostCount() {
+        return manager.getVirtualHosts(this.networkId()).size();
+    }
+
+    @Override
+    public Iterable<Host> getHosts() {
+        return getHostsColl();
+    }
+
+    @Override
+    public Host getHost(HostId hostId) {
+        checkNotNull(hostId, HOST_NULL);
+        Optional<VirtualHost> foundHost =
+                manager.getVirtualHosts(this.networkId())
+                .stream()
+                .filter(host -> hostId.equals(host.id()))
+                .findFirst();
+        if (foundHost.isPresent()) {
+            return foundHost.get();
+        }
+        return null;
+    }
+
+    /**
+     * Gets a collection of virtual hosts.
+     *
+     * @return collection of virtual hosts.
+     */
+    private Collection<Host> getHostsColl() {
+        return manager.getVirtualHosts(this.networkId())
+                .stream().collect(Collectors.toSet());
+    }
+
+    /**
+     * Filters specified collection.
+     *
+     * @param collection collection of hosts to filter
+     * @param predicate condition to filter on
+     * @return collection of virtual hosts that satisfy the filter condition
+     */
+    private Set<Host> filter(Collection<Host> collection, Predicate<Host> predicate) {
+        return collection.stream().filter(predicate).collect(Collectors.toSet());
+    }
+
+    @Override
+    public Set<Host> getHostsByVlan(VlanId vlanId) {
+        checkNotNull(vlanId, "VLAN identifier cannot be null");
+        return filter(getHostsColl(), host -> Objects.equals(host.vlan(), vlanId));
+    }
+
+    @Override
+    public Set<Host> getHostsByMac(MacAddress mac) {
+        checkNotNull(mac, "MAC address cannot be null");
+        return filter(getHostsColl(), host -> Objects.equals(host.mac(), mac));
+    }
+
+    @Override
+    public Set<Host> getHostsByIp(IpAddress ip) {
+        checkNotNull(ip, "IP address cannot be null");
+        return filter(getHostsColl(), host -> host.ipAddresses().contains(ip));
+    }
+
+    @Override
+    public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+        checkNotNull(connectPoint, "Connect point cannot be null");
+        return filter(getHostsColl(), host -> host.location().equals(connectPoint));
+    }
+
+    @Override
+    public Set<Host> getConnectedHosts(DeviceId deviceId) {
+        checkNotNull(deviceId, "Device identifier cannot be null");
+        return filter(getHostsColl(), host -> host.location().deviceId().equals(deviceId));
+    }
+
+    @Override
+    public void startMonitoringIp(IpAddress ip) {
+        //TODO check what needs to be done here
+    }
+
+    @Override
+    public void stopMonitoringIp(IpAddress ip) {
+        //TODO check what needs to be done here
+    }
+
+    @Override
+    public void requestMac(IpAddress ip) {
+        //TODO check what needs to be done here
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentManager.java
new file mode 100644
index 0000000..f4c1137
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentManager.java
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2018-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 org.onlab.util.Tools;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntentStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.incubator.net.virtual.VnetService;
+import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
+import org.onosproject.incubator.net.virtual.impl.intent.phase.VirtualFinalIntentProcessPhase;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentInstallCoordinator;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentAccumulator;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentCompilerRegistry;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentInstallerRegistry;
+import org.onosproject.incubator.net.virtual.impl.intent.phase.VirtualIntentProcessPhase;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentProcessor;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentSkipped;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentBatchDelegate;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.IntentStoreDelegate;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.resource.ResourceConsumer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.*;
+import static org.onlab.util.BoundedThreadPool.newFixedThreadPool;
+import static org.onlab.util.BoundedThreadPool.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.incubator.net.virtual.impl.intent.phase.VirtualIntentProcessPhase.newInitialPhase;
+import static org.onosproject.net.intent.IntentState.FAILED;
+
+/**
+ * Intent service implementation built on the virtual network service.
+ */
+public class VirtualNetworkIntentManager
+        extends AbstractVirtualListenerManager<IntentEvent, IntentListener>
+        implements IntentService, VnetService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final int DEFAULT_NUM_THREADS = 12;
+    private int numThreads = DEFAULT_NUM_THREADS;
+
+    private static final String NETWORK_ID_NULL = "Network ID cannot be null";
+    private static final String DEVICE_NULL = "Device cannot be null";
+    private static final String INTENT_NULL = "Intent cannot be null";
+    private static final String KEY_NULL = "Key cannot be null";
+    private static final String APP_ID_NULL = "Intent app identifier cannot be null";
+    private static final String INTENT_KEY_NULL = "Intent key cannot be null";
+    private static final String CP_NULL = "Connect Point cannot be null";
+
+    //FIXME: Tracker service for vnet.
+
+    //ONOS core services
+    protected VirtualNetworkStore virtualNetworkStore;
+    protected VirtualNetworkIntentStore intentStore;
+
+    //Virtual network services
+    protected GroupService groupService;
+
+    private final IntentBatchDelegate batchDelegate = new InternalBatchDelegate();
+    private final InternalIntentProcessor processor = new InternalIntentProcessor();
+    private final IntentStoreDelegate delegate = new InternalStoreDelegate();
+    private final VirtualIntentCompilerRegistry compilerRegistry =
+            VirtualIntentCompilerRegistry.getInstance();
+    private final VirtualIntentInstallerRegistry installerRegistry =
+            VirtualIntentInstallerRegistry.getInstance();
+    private final VirtualIntentAccumulator accumulator =
+            new VirtualIntentAccumulator(batchDelegate);
+
+    private VirtualIntentInstallCoordinator installCoordinator;
+    private ExecutorService batchExecutor;
+    private ExecutorService workerExecutor;
+
+    /**
+     * Creates a new VirtualNetworkIntentService object.
+     *
+     * @param virtualNetworkManager virtual network manager service
+     * @param networkId a virtual network identifier
+     */
+    public VirtualNetworkIntentManager(VirtualNetworkService virtualNetworkManager,
+                                       NetworkId networkId) {
+
+        super(virtualNetworkManager, networkId, IntentEvent.class);
+
+        this.virtualNetworkStore = serviceDirectory.get(VirtualNetworkStore.class);
+        this.intentStore = serviceDirectory.get(VirtualNetworkIntentStore.class);
+
+        this.groupService = manager.get(networkId, GroupService.class);
+
+        intentStore.setDelegate(networkId, delegate);
+        batchExecutor = newSingleThreadExecutor(groupedThreads("onos/intent", "batch", log));
+        workerExecutor = newFixedThreadPool(numThreads, groupedThreads("onos/intent", "worker-%d", log));
+
+        installCoordinator = new VirtualIntentInstallCoordinator(networkId, installerRegistry, intentStore);
+        log.info("Started");
+
+    }
+
+    @Override
+    public void submit(Intent intent) {
+        checkNotNull(intent, INTENT_NULL);
+        checkState(intent instanceof VirtualNetworkIntent, "Only VirtualNetworkIntent is supported.");
+        checkArgument(validateIntent((VirtualNetworkIntent) intent), "Invalid Intent");
+
+        IntentData data = IntentData.submit(intent);
+        intentStore.addPending(networkId, data);
+    }
+
+    /**
+     * Returns true if the virtual network intent is valid.
+     *
+     * @param intent virtual network intent
+     * @return true if intent is valid
+     */
+    private boolean validateIntent(VirtualNetworkIntent intent) {
+        checkNotNull(intent, INTENT_NULL);
+        checkNotNull(intent.networkId(), NETWORK_ID_NULL);
+        checkNotNull(intent.appId(), APP_ID_NULL);
+        checkNotNull(intent.key(), INTENT_KEY_NULL);
+        ConnectPoint ingressPoint = intent.ingressPoint();
+        ConnectPoint egressPoint = intent.egressPoint();
+
+        return (validateConnectPoint(ingressPoint) && validateConnectPoint(egressPoint));
+    }
+
+    /**
+     * Returns true if the connect point is valid.
+     *
+     * @param connectPoint connect point
+     * @return true if connect point is valid
+     */
+    private boolean validateConnectPoint(ConnectPoint connectPoint) {
+        checkNotNull(connectPoint, CP_NULL);
+        Port port = getPort(connectPoint.deviceId(), connectPoint.port());
+        return port != null;
+    }
+
+    /**
+     * Returns the virtual port for the given device identifier and port number.
+     *
+     * @param deviceId   virtual device identifier
+     * @param portNumber virtual port number
+     * @return virtual port
+     */
+    private Port getPort(DeviceId deviceId, PortNumber portNumber) {
+        checkNotNull(deviceId, DEVICE_NULL);
+
+        Optional<VirtualPort> foundPort = manager.getVirtualPorts(this.networkId(), deviceId)
+                .stream()
+                .filter(port -> port.number().equals(portNumber))
+                .findFirst();
+        if (foundPort.isPresent()) {
+            return foundPort.get();
+        }
+        return null;
+    }
+
+    @Override
+    public void withdraw(Intent intent) {
+        checkNotNull(intent, INTENT_NULL);
+        IntentData data = IntentData.withdraw(intent);
+        intentStore.addPending(networkId, data);
+    }
+
+    @Override
+    public void purge(Intent intent) {
+        checkNotNull(intent, INTENT_NULL);
+
+        IntentData data = IntentData.purge(intent);
+        intentStore.addPending(networkId, data);
+
+        // remove associated group if there is one
+        // FIXME: Remove P2P intent for vnets
+    }
+
+    @Override
+    public Intent getIntent(Key key) {
+        checkNotNull(key, KEY_NULL);
+        return intentStore.getIntent(networkId, key);
+    }
+
+    @Override
+    public Iterable<Intent> getIntents() {
+        return intentStore.getIntents(networkId);
+    }
+
+    @Override
+    public void addPending(IntentData intentData) {
+        checkNotNull(intentData, INTENT_NULL);
+        //TODO we might consider further checking / assertions
+        intentStore.addPending(networkId, intentData);
+    }
+
+    @Override
+    public Iterable<IntentData> getIntentData() {
+        return intentStore.getIntentData(networkId, false, 0);
+    }
+
+    @Override
+    public long getIntentCount() {
+        return intentStore.getIntentCount(networkId);
+    }
+
+    @Override
+    public IntentState getIntentState(Key intentKey) {
+        checkNotNull(intentKey, KEY_NULL);
+        return intentStore.getIntentState(networkId, intentKey);
+    }
+
+    @Override
+    public List<Intent> getInstallableIntents(Key intentKey) {
+        return intentStore.getInstallableIntents(networkId, intentKey);
+    }
+
+    @Override
+    public boolean isLocal(Key intentKey) {
+        return intentStore.isMaster(networkId, intentKey);
+    }
+
+    @Override
+    public Iterable<Intent> getPending() {
+        return intentStore.getPending(networkId);
+    }
+
+    // Store delegate to re-post events emitted from the store.
+    private class InternalStoreDelegate implements IntentStoreDelegate {
+        @Override
+        public void notify(IntentEvent event) {
+            post(event);
+            switch (event.type()) {
+                case WITHDRAWN:
+                    //FIXME: release resources
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        @Override
+        public void process(IntentData data) {
+            accumulator.add(data);
+        }
+
+        @Override
+        public void onUpdate(IntentData intentData) {
+            //FIXME: track intent
+        }
+
+        private void releaseResources(Intent intent) {
+            // If a resource group is set on the intent, the resource consumer is
+            // set equal to it. Otherwise it's set to the intent key
+            ResourceConsumer resourceConsumer =
+                    intent.resourceGroup() != null ? intent.resourceGroup() : intent.key();
+
+            // By default the resource doesn't get released
+            boolean removeResource = false;
+
+            if (intent.resourceGroup() == null) {
+                // If the intent doesn't have a resource group, it means the
+                // resource was registered using the intent key, so it can be
+                // released
+                removeResource = true;
+            } else {
+                // When a resource group is set, we make sure there are no other
+                // intents using the same resource group, before deleting the
+                // related resources.
+                Long remainingIntents =
+                        Tools.stream(intentStore.getIntents(networkId))
+                                .filter(i -> {
+                                    return i.resourceGroup() != null
+                                            && i.resourceGroup().equals(intent.resourceGroup());
+                                })
+                                .count();
+                if (remainingIntents == 0) {
+                    removeResource = true;
+                }
+            }
+
+            if (removeResource) {
+                // Release resources allocated to withdrawn intent
+                // FIXME: confirm resources are released
+            }
+        }
+    }
+
+    private class InternalBatchDelegate implements IntentBatchDelegate {
+        @Override
+        public void execute(Collection<IntentData> operations) {
+            log.debug("Execute {} operation(s).", operations.size());
+            log.trace("Execute operations: {}", operations);
+
+            // batchExecutor is single-threaded, so only one batch is in flight at a time
+            CompletableFuture.runAsync(() -> {
+                // process intent until the phase reaches one of the final phases
+                List<CompletableFuture<IntentData>> futures = operations.stream()
+                        .map(data -> {
+                            log.debug("Start processing of {} {}@{}", data.request(), data.key(), data.version());
+                            return data;
+                        })
+                        .map(x -> CompletableFuture.completedFuture(x)
+                                .thenApply(VirtualNetworkIntentManager.this::createInitialPhase)
+                                .thenApplyAsync(VirtualIntentProcessPhase::process, workerExecutor)
+                                .thenApply(VirtualFinalIntentProcessPhase::data)
+                                .exceptionally(e -> {
+                                    // When the future fails, we update the Intent to simulate the failure of
+                                    // the installation/withdrawal phase and we save in the current map. In
+                                    // the next round the CleanUp Thread will pick this Intent again.
+                                    log.warn("Future failed", e);
+                                    log.warn("Intent {} - state {} - request {}",
+                                             x.key(), x.state(), x.request());
+                                    switch (x.state()) {
+                                        case INSTALL_REQ:
+                                        case INSTALLING:
+                                        case WITHDRAW_REQ:
+                                        case WITHDRAWING:
+                                            // TODO should we swtich based on current
+                                            IntentData current = intentStore.getIntentData(networkId, x.key());
+                                            return IntentData.nextState(current, FAILED);
+                                        default:
+                                            return null;
+                                    }
+                                }))
+                        .collect(Collectors.toList());
+
+                // write multiple data to store in order
+                intentStore.batchWrite(networkId, Tools.allOf(futures).join().stream()
+                                         .filter(Objects::nonNull)
+                                         .collect(Collectors.toList()));
+            }, batchExecutor).exceptionally(e -> {
+                log.error("Error submitting batches:", e);
+                // FIXME incomplete Intents should be cleaned up
+                //       (transition to FAILED, etc.)
+
+                // the batch has failed
+                // TODO: maybe we should do more?
+                log.error("Walk the plank, matey...");
+                return null;
+            }).thenRun(accumulator::ready);
+
+        }
+    }
+
+    private VirtualIntentProcessPhase createInitialPhase(IntentData data) {
+        IntentData pending = intentStore.getPendingData(networkId, data.key());
+        if (pending == null || pending.version().isNewerThan(data.version())) {
+            /*
+                If the pending map is null, then this intent was compiled by a
+                previous batch iteration, so we can skip it.
+                If the pending map has a newer request, it will get compiled as
+                part of the next batch, so we can skip it.
+             */
+            return VirtualIntentSkipped.getPhase();
+        }
+        IntentData current = intentStore.getIntentData(networkId, data.key());
+        return newInitialPhase(networkId, processor, data, current);
+    }
+
+    private class InternalIntentProcessor implements VirtualIntentProcessor {
+        @Override
+        public List<Intent> compile(NetworkId networkId,
+                                    Intent intent,
+                                    List<Intent> previousInstallables) {
+            return compilerRegistry.compile(networkId, intent, previousInstallables);
+        }
+
+        @Override
+        public void apply(NetworkId networkId,
+                          Optional<IntentData> toUninstall,
+                          Optional<IntentData> toInstall) {
+
+            installCoordinator.installIntents(toUninstall, toInstall);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManager.java
new file mode 100644
index 0000000..1a1c2bf
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManager.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2018-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 org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+import org.onosproject.net.link.LinkService;
+
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Link service implementation built on the virtual network service.
+ */
+public class VirtualNetworkLinkManager
+        extends AbstractVirtualListenerManager<LinkEvent, LinkListener>
+        implements LinkService {
+
+    private static final String DEVICE_NULL = "Device cannot be null";
+    private static final String CONNECT_POINT_NULL = "Connect point cannot be null";
+
+    /**
+     * Creates a new VirtualNetworkLinkService object.
+     *
+     * @param virtualNetworkManager virtual network manager service
+     * @param networkId a virtual networkIdentifier
+     */
+    public VirtualNetworkLinkManager(VirtualNetworkService virtualNetworkManager,
+                                     NetworkId networkId) {
+        super(virtualNetworkManager, networkId, LinkEvent.class);
+    }
+
+    @Override
+    public int getLinkCount() {
+        return manager.getVirtualLinks(this.networkId()).size();
+    }
+
+    @Override
+    public Iterable<Link> getLinks() {
+        return manager.getVirtualLinks(this.networkId())
+                .stream().collect(Collectors.toSet());
+    }
+
+    @Override
+    public Iterable<Link> getActiveLinks() {
+
+        return manager.getVirtualLinks(this.networkId())
+                .stream()
+                .filter(link -> (link.state().equals(Link.State.ACTIVE)))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public Set<Link> getDeviceLinks(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_NULL);
+        return manager.getVirtualLinks(this.networkId())
+                .stream()
+                .filter(link -> (deviceId.equals(link.src().elementId()) ||
+                        deviceId.equals(link.dst().elementId())))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public Set<Link> getDeviceEgressLinks(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_NULL);
+        return manager.getVirtualLinks(this.networkId())
+                .stream()
+                .filter(link -> (deviceId.equals(link.dst().elementId())))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public Set<Link> getDeviceIngressLinks(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_NULL);
+        return manager.getVirtualLinks(this.networkId())
+                .stream()
+                .filter(link -> (deviceId.equals(link.src().elementId())))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public Set<Link> getLinks(ConnectPoint connectPoint) {
+        checkNotNull(connectPoint, CONNECT_POINT_NULL);
+        return manager.getVirtualLinks(this.networkId())
+                .stream()
+                .filter(link -> (connectPoint.equals(link.src()) ||
+                        connectPoint.equals(link.dst())))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public Set<Link> getEgressLinks(ConnectPoint connectPoint) {
+        checkNotNull(connectPoint, CONNECT_POINT_NULL);
+        return manager.getVirtualLinks(this.networkId())
+                .stream()
+                .filter(link -> (connectPoint.equals(link.dst())))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public Set<Link> getIngressLinks(ConnectPoint connectPoint) {
+        checkNotNull(connectPoint, CONNECT_POINT_NULL);
+        return manager.getVirtualLinks(this.networkId())
+                .stream()
+                .filter(link -> (connectPoint.equals(link.src())))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public Link getLink(ConnectPoint src, ConnectPoint dst) {
+        checkNotNull(src, CONNECT_POINT_NULL);
+        checkNotNull(dst, CONNECT_POINT_NULL);
+        Optional<VirtualLink> foundLink =  manager.getVirtualLinks(this.networkId())
+                .stream()
+                .filter(link -> (src.equals(link.src()) &&
+                        dst.equals(link.dst())))
+                .findFirst();
+
+        if (foundLink.isPresent()) {
+            return foundLink.get();
+        }
+        return null;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java
new file mode 100644
index 0000000..3b4ed8c
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java
@@ -0,0 +1,628 @@
+/*
+ * Copyright 2018-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.ImmutableSet;
+import com.google.common.collect.Maps;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
+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.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkListener;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.incubator.net.virtual.VnetService;
+import org.onosproject.incubator.net.virtual.event.VirtualEvent;
+import org.onosproject.incubator.net.virtual.event.VirtualListenerRegistryManager;
+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.mastership.MastershipAdminService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.mastership.MastershipTermService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.meter.MeterService;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.provider.AbstractListenerProviderRegistry;
+import org.onosproject.net.provider.AbstractProviderService;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.net.topology.TopologyService;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Implementation of the virtual network service.
+ */
+@Component(service = {
+                   VirtualNetworkService.class,
+                   VirtualNetworkAdminService.class,
+                   VirtualNetworkService.class,
+                   VirtualNetworkProviderRegistry.class
+            })
+public class VirtualNetworkManager
+        extends AbstractListenerProviderRegistry<VirtualNetworkEvent,
+        VirtualNetworkListener, VirtualNetworkProvider, VirtualNetworkProviderService>
+        implements VirtualNetworkService, VirtualNetworkAdminService, VirtualNetworkProviderRegistry {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final String TENANT_NULL = "Tenant ID cannot be null";
+    private static final String NETWORK_NULL = "Network ID cannot be null";
+    private static final String DEVICE_NULL = "Device ID cannot be null";
+    private static final String LINK_POINT_NULL = "Link end-point cannot be null";
+
+    private static final String VIRTUAL_NETWORK_APP_ID_STRING =
+            "org.onosproject.virtual-network";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected VirtualNetworkStore store;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected CoreService coreService;
+
+    private VirtualNetworkStoreDelegate delegate = this::post;
+
+    private ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
+    private ApplicationId appId;
+
+    // TODO: figure out how to coordinate "implementation" of a virtual network in a cluster
+
+    /**
+     * Only used for Junit test methods outside of this package.
+     *
+     * @param store virtual network store
+     */
+    public void setStore(VirtualNetworkStore store) {
+        this.store = store;
+    }
+
+    @Activate
+    public void activate() {
+        eventDispatcher.addSink(VirtualNetworkEvent.class, listenerRegistry);
+        eventDispatcher.addSink(VirtualEvent.class,
+                                VirtualListenerRegistryManager.getInstance());
+        store.setDelegate(delegate);
+        appId = coreService.registerApplication(VIRTUAL_NETWORK_APP_ID_STRING);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        store.unsetDelegate(delegate);
+        eventDispatcher.removeSink(VirtualNetworkEvent.class);
+        eventDispatcher.removeSink(VirtualEvent.class);
+        log.info("Stopped");
+    }
+
+    @Override
+    public void registerTenantId(TenantId tenantId) {
+        checkNotNull(tenantId, TENANT_NULL);
+        store.addTenantId(tenantId);
+    }
+
+    @Override
+    public void unregisterTenantId(TenantId tenantId) {
+        checkNotNull(tenantId, TENANT_NULL);
+        store.removeTenantId(tenantId);
+    }
+
+    @Override
+    public Set<TenantId> getTenantIds() {
+        return store.getTenantIds();
+    }
+
+    @Override
+    public VirtualNetwork createVirtualNetwork(TenantId tenantId) {
+        checkNotNull(tenantId, TENANT_NULL);
+        return store.addNetwork(tenantId);
+    }
+
+    @Override
+    public void removeVirtualNetwork(NetworkId networkId) {
+        checkNotNull(networkId, NETWORK_NULL);
+        store.removeNetwork(networkId);
+    }
+
+    @Override
+    public VirtualDevice createVirtualDevice(NetworkId networkId, DeviceId deviceId) {
+        checkNotNull(networkId, NETWORK_NULL);
+        checkNotNull(deviceId, DEVICE_NULL);
+        return store.addDevice(networkId, deviceId);
+    }
+
+    @Override
+    public void removeVirtualDevice(NetworkId networkId, DeviceId deviceId) {
+        checkNotNull(networkId, NETWORK_NULL);
+        checkNotNull(deviceId, DEVICE_NULL);
+        store.removeDevice(networkId, deviceId);
+    }
+
+    @Override
+    public VirtualHost createVirtualHost(NetworkId networkId, HostId hostId,
+                                         MacAddress mac, VlanId vlan,
+                                         HostLocation location, Set<IpAddress> ips) {
+        checkNotNull(networkId, NETWORK_NULL);
+        checkNotNull(hostId, DEVICE_NULL);
+        return store.addHost(networkId, hostId, mac, vlan, location, ips);
+    }
+
+    @Override
+    public void removeVirtualHost(NetworkId networkId, HostId hostId) {
+        checkNotNull(networkId, NETWORK_NULL);
+        checkNotNull(hostId, DEVICE_NULL);
+        store.removeHost(networkId, hostId);
+    }
+
+    @Override
+    public VirtualLink createVirtualLink(NetworkId networkId,
+                                         ConnectPoint src, ConnectPoint dst) {
+        checkNotNull(networkId, NETWORK_NULL);
+        checkNotNull(src, LINK_POINT_NULL);
+        checkNotNull(dst, LINK_POINT_NULL);
+        ConnectPoint physicalSrc = mapVirtualToPhysicalPort(networkId, src);
+        checkNotNull(physicalSrc, LINK_POINT_NULL);
+        ConnectPoint physicalDst = mapVirtualToPhysicalPort(networkId, dst);
+        checkNotNull(physicalDst, LINK_POINT_NULL);
+
+        VirtualNetworkProvider provider = getProvider(DefaultVirtualLink.PID);
+        Link.State state = Link.State.INACTIVE;
+        if (provider != null) {
+            boolean traversable = provider.isTraversable(physicalSrc, physicalDst);
+            state = traversable ? Link.State.ACTIVE : Link.State.INACTIVE;
+        }
+        return store.addLink(networkId, src, dst, state, null);
+    }
+
+    /**
+     * Maps the virtual connect point to a physical connect point.
+     *
+     * @param networkId network identifier
+     * @param virtualCp virtual connect point
+     * @return physical connect point
+     */
+    private ConnectPoint mapVirtualToPhysicalPort(NetworkId networkId,
+                                                  ConnectPoint virtualCp) {
+        Set<VirtualPort> ports = store.getPorts(networkId, virtualCp.deviceId());
+        for (VirtualPort port : ports) {
+            if (port.number().equals(virtualCp.port())) {
+                return new ConnectPoint(port.realizedBy().deviceId(),
+                                        port.realizedBy().port());
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Maps the physical connect point to a virtual connect point.
+     *
+     * @param networkId  network identifier
+     * @param physicalCp physical connect point
+     * @return virtual connect point
+     */
+    private ConnectPoint mapPhysicalToVirtualToPort(NetworkId networkId,
+                                                    ConnectPoint physicalCp) {
+        Set<VirtualPort> ports = store.getPorts(networkId, null);
+        for (VirtualPort port : ports) {
+            if (port.realizedBy().deviceId().equals(physicalCp.elementId()) &&
+                    port.realizedBy().port().equals(physicalCp.port())) {
+                return new ConnectPoint(port.element().id(), port.number());
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void removeVirtualLink(NetworkId networkId, ConnectPoint src,
+                                  ConnectPoint dst) {
+        checkNotNull(networkId, NETWORK_NULL);
+        checkNotNull(src, LINK_POINT_NULL);
+        checkNotNull(dst, LINK_POINT_NULL);
+        store.removeLink(networkId, src, dst);
+    }
+
+    @Override
+    public VirtualPort createVirtualPort(NetworkId networkId, DeviceId deviceId,
+                                         PortNumber portNumber, ConnectPoint realizedBy) {
+        checkNotNull(networkId, NETWORK_NULL);
+        checkNotNull(deviceId, DEVICE_NULL);
+        checkNotNull(portNumber, "Port description cannot be null");
+        return store.addPort(networkId, deviceId, portNumber, realizedBy);
+    }
+
+    @Override
+    public void bindVirtualPort(NetworkId networkId, DeviceId deviceId,
+                PortNumber portNumber, ConnectPoint realizedBy) {
+        checkNotNull(networkId, NETWORK_NULL);
+        checkNotNull(deviceId, DEVICE_NULL);
+        checkNotNull(portNumber, "Port description cannot be null");
+        checkNotNull(realizedBy, "Physical port description cannot be null");
+
+        store.bindPort(networkId, deviceId, portNumber, realizedBy);
+    }
+
+    @Override
+    public void updatePortState(NetworkId networkId, DeviceId deviceId,
+                PortNumber portNumber, boolean isEnabled) {
+        checkNotNull(networkId, NETWORK_NULL);
+        checkNotNull(deviceId, DEVICE_NULL);
+        checkNotNull(portNumber, "Port description cannot be null");
+
+        store.updatePortState(networkId, deviceId, portNumber, isEnabled);
+    }
+
+    @Override
+    public void removeVirtualPort(NetworkId networkId, DeviceId deviceId,
+                                  PortNumber portNumber) {
+        checkNotNull(networkId, NETWORK_NULL);
+        checkNotNull(deviceId, DEVICE_NULL);
+        checkNotNull(portNumber, "Port number cannot be null");
+        store.removePort(networkId, deviceId, portNumber);
+    }
+
+    @Override
+    public ServiceDirectory getServiceDirectory() {
+        return serviceDirectory;
+    }
+
+    @Override
+    public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
+        checkNotNull(tenantId, TENANT_NULL);
+        return store.getNetworks(tenantId);
+    }
+
+    @Override
+    public VirtualNetwork getVirtualNetwork(NetworkId networkId) {
+        checkNotNull(networkId, NETWORK_NULL);
+        return store.getNetwork(networkId);
+    }
+
+    @Override
+    public TenantId getTenantId(NetworkId networkId) {
+        VirtualNetwork virtualNetwork = getVirtualNetwork(networkId);
+        checkNotNull(virtualNetwork, "The network does not exist.");
+        return virtualNetwork.tenantId();
+    }
+
+    @Override
+    public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
+        checkNotNull(networkId, NETWORK_NULL);
+        return store.getDevices(networkId);
+    }
+
+    @Override
+    public Set<VirtualHost> getVirtualHosts(NetworkId networkId) {
+        checkNotNull(networkId, NETWORK_NULL);
+        return store.getHosts(networkId);
+    }
+
+    @Override
+    public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
+        checkNotNull(networkId, NETWORK_NULL);
+        return store.getLinks(networkId);
+    }
+
+    @Override
+    public Set<VirtualPort> getVirtualPorts(NetworkId networkId, DeviceId deviceId) {
+        checkNotNull(networkId, NETWORK_NULL);
+        return store.getPorts(networkId, deviceId);
+    }
+
+    @Override
+    public Set<DeviceId> getPhysicalDevices(NetworkId networkId, DeviceId deviceId) {
+        checkNotNull(networkId, "Network ID cannot be null");
+        checkNotNull(deviceId, "Virtual device ID cannot be null");
+        Set<VirtualPort> virtualPortSet = getVirtualPorts(networkId, deviceId);
+        Set<DeviceId> physicalDeviceSet = new HashSet<>();
+
+        virtualPortSet.forEach(virtualPort -> {
+            if (virtualPort.realizedBy() != null) {
+                physicalDeviceSet.add(virtualPort.realizedBy().deviceId());
+            }
+        });
+
+        return ImmutableSet.copyOf(physicalDeviceSet);
+    }
+
+    private final Map<ServiceKey, VnetService> networkServices = Maps.newConcurrentMap();
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T> T get(NetworkId networkId, Class<T> serviceClass) {
+        checkNotNull(networkId, NETWORK_NULL);
+        ServiceKey serviceKey = networkServiceKey(networkId, serviceClass);
+        VnetService service = lookup(serviceKey);
+        if (service == null) {
+            service = create(serviceKey);
+        }
+        return (T) service;
+    }
+
+    @Override
+    public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) {
+        return appId;
+    }
+
+    /**
+     * Returns the Vnet service matching the service key.
+     *
+     * @param serviceKey service key
+     * @return vnet service
+     */
+    private VnetService lookup(ServiceKey serviceKey) {
+        return networkServices.get(serviceKey);
+    }
+
+    /**
+     * Creates a new service key using the specified network identifier and service class.
+     *
+     * @param networkId    network identifier
+     * @param serviceClass service class
+     * @param <T>          type of service
+     * @return service key
+     */
+    private <T> ServiceKey networkServiceKey(NetworkId networkId, Class<T> serviceClass) {
+        return new ServiceKey(networkId, serviceClass);
+    }
+
+
+    /**
+     * Create a new vnet service instance.
+     *
+     * @param serviceKey service key
+     * @return vnet service
+     */
+    private VnetService create(ServiceKey serviceKey) {
+        VirtualNetwork network = getVirtualNetwork(serviceKey.networkId());
+        checkNotNull(network, NETWORK_NULL);
+
+        VnetService service;
+        if (serviceKey.serviceClass.equals(DeviceService.class)) {
+            service = new VirtualNetworkDeviceManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(LinkService.class)) {
+            service = new VirtualNetworkLinkManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(TopologyService.class)) {
+            service = new VirtualNetworkTopologyManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(IntentService.class)) {
+            service = new VirtualNetworkIntentManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(HostService.class)) {
+            service = new VirtualNetworkHostManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(PathService.class)) {
+            service = new VirtualNetworkPathManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(FlowRuleService.class)) {
+            service = new VirtualNetworkFlowRuleManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(PacketService.class)) {
+            service = new VirtualNetworkPacketManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(GroupService.class)) {
+            service = new VirtualNetworkGroupManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(MeterService.class)) {
+            service = new VirtualNetworkMeterManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(FlowObjectiveService.class)) {
+            service = new VirtualNetworkFlowObjectiveManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(MastershipService.class) ||
+                serviceKey.serviceClass.equals(MastershipAdminService.class) ||
+                serviceKey.serviceClass.equals(MastershipTermService.class)) {
+            service = new VirtualNetworkMastershipManager(this, network.id());
+        } else {
+            return null;
+        }
+        networkServices.put(serviceKey, service);
+        return service;
+    }
+
+    /**
+     * Service key class.
+     */
+    private static class ServiceKey {
+        final NetworkId networkId;
+        final Class serviceClass;
+
+        /**
+         * Constructor for service key.
+         *
+         * @param networkId    network identifier
+         * @param serviceClass service class
+         */
+        ServiceKey(NetworkId networkId, Class serviceClass) {
+
+            checkNotNull(networkId, NETWORK_NULL);
+            this.networkId = networkId;
+            this.serviceClass = serviceClass;
+        }
+
+        /**
+         * Returns the network identifier.
+         *
+         * @return network identifier
+         */
+        public NetworkId networkId() {
+            return networkId;
+        }
+
+        /**
+         * Returns the service class.
+         *
+         * @return service class
+         */
+        public Class serviceClass() {
+            return serviceClass;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(networkId, serviceClass);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof ServiceKey) {
+                ServiceKey that = (ServiceKey) obj;
+                return Objects.equals(this.networkId, that.networkId) &&
+                        Objects.equals(this.serviceClass, that.serviceClass);
+            }
+            return false;
+        }
+    }
+
+    @Override
+    protected VirtualNetworkProviderService
+    createProviderService(VirtualNetworkProvider provider) {
+        return new InternalVirtualNetworkProviderService(provider);
+    }
+
+    /**
+     * Service issued to registered virtual network providers so that they
+     * can interact with the core.
+     */
+    private class InternalVirtualNetworkProviderService
+            extends AbstractProviderService<VirtualNetworkProvider>
+            implements VirtualNetworkProviderService {
+        /**
+         * Constructor.
+         * @param provider virtual network provider
+         */
+        InternalVirtualNetworkProviderService(VirtualNetworkProvider provider) {
+            super(provider);
+        }
+
+        @Override
+        public void topologyChanged(Set<Set<ConnectPoint>> clusters) {
+            Set<TenantId> tenantIds = getTenantIds();
+            tenantIds.forEach(tenantId -> {
+                Set<VirtualNetwork> virtualNetworks = getVirtualNetworks(tenantId);
+
+                virtualNetworks.forEach(virtualNetwork -> {
+                    Set<VirtualLink> virtualLinks = getVirtualLinks(virtualNetwork.id());
+
+                    virtualLinks.forEach(virtualLink -> {
+                        if (isVirtualLinkInCluster(virtualNetwork.id(),
+                                                   virtualLink, clusters)) {
+                            store.updateLink(virtualLink, virtualLink.tunnelId(),
+                                             Link.State.ACTIVE);
+                        } else {
+                            store.updateLink(virtualLink, virtualLink.tunnelId(),
+                                             Link.State.INACTIVE);
+                        }
+                    });
+                });
+            });
+        }
+
+        /**
+         * Determines if the virtual link (both source and destination connect point)
+         * is in a cluster.
+         *
+         * @param networkId   virtual network identifier
+         * @param virtualLink virtual link
+         * @param clusters    topology clusters
+         * @return true if the virtual link is in a cluster.
+         */
+        private boolean isVirtualLinkInCluster(NetworkId networkId, VirtualLink virtualLink,
+                                               Set<Set<ConnectPoint>> clusters) {
+            ConnectPoint srcPhysicalCp =
+                    mapVirtualToPhysicalPort(networkId, virtualLink.src());
+            ConnectPoint dstPhysicalCp =
+                    mapVirtualToPhysicalPort(networkId, virtualLink.dst());
+
+            final boolean[] foundSrc = {false};
+            final boolean[] foundDst = {false};
+            clusters.forEach(connectPoints -> {
+                connectPoints.forEach(connectPoint -> {
+                    if (connectPoint.equals(srcPhysicalCp)) {
+                        foundSrc[0] = true;
+                    } else if (connectPoint.equals(dstPhysicalCp)) {
+                        foundDst[0] = true;
+                    }
+                });
+                if (foundSrc[0] && foundDst[0]) {
+                    return;
+                }
+            });
+            return foundSrc[0] && foundDst[0];
+        }
+
+        @Override
+        public void tunnelUp(NetworkId networkId, ConnectPoint src,
+                             ConnectPoint dst, TunnelId tunnelId) {
+            ConnectPoint srcVirtualCp = mapPhysicalToVirtualToPort(networkId, src);
+            ConnectPoint dstVirtualCp = mapPhysicalToVirtualToPort(networkId, dst);
+            if ((srcVirtualCp == null) || (dstVirtualCp == null)) {
+                log.error("Src or dst virtual connection point was not found.");
+            }
+
+            VirtualLink virtualLink = store.getLink(networkId, srcVirtualCp, dstVirtualCp);
+            if (virtualLink != null) {
+                store.updateLink(virtualLink, tunnelId, Link.State.ACTIVE);
+            }
+        }
+
+        @Override
+        public void tunnelDown(NetworkId networkId, ConnectPoint src,
+                               ConnectPoint dst, TunnelId tunnelId) {
+            ConnectPoint srcVirtualCp = mapPhysicalToVirtualToPort(networkId, src);
+            ConnectPoint dstVirtualCp = mapPhysicalToVirtualToPort(networkId, dst);
+            if ((srcVirtualCp == null) || (dstVirtualCp == null)) {
+                log.error("Src or dst virtual connection point was not found.");
+            }
+
+            VirtualLink virtualLink = store.getLink(networkId, srcVirtualCp, dstVirtualCp);
+            if (virtualLink != null) {
+                store.updateLink(virtualLink, tunnelId, Link.State.INACTIVE);
+            }
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManager.java
new file mode 100644
index 0000000..57c0774
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManager.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2018-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.Lists;
+import com.google.common.util.concurrent.Futures;
+import org.onlab.metrics.MetricsService;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.cluster.RoleInfo;
+import org.onosproject.core.MetricsHelper;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetworkMastershipStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
+import org.onosproject.mastership.MastershipAdminService;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipInfo;
+import org.onosproject.mastership.MastershipListener;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.mastership.MastershipStoreDelegate;
+import org.onosproject.mastership.MastershipTerm;
+import org.onosproject.mastership.MastershipTermService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.slf4j.Logger;
+import com.codahale.metrics.Timer;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.metrics.MetricsUtil.startTimer;
+import static org.onlab.metrics.MetricsUtil.stopTimer;
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class VirtualNetworkMastershipManager
+        extends AbstractVirtualListenerManager<MastershipEvent, MastershipListener>
+        implements MastershipService, MastershipAdminService, MastershipTermService,
+        MetricsHelper {
+
+    private static final String NODE_ID_NULL = "Node ID cannot be null";
+    private static final String DEVICE_ID_NULL = "Device ID cannot be null";
+    private static final String ROLE_NULL = "Mastership role cannot be null";
+
+    private final Logger log = getLogger(getClass());
+
+    protected ClusterService clusterService;
+
+    VirtualNetworkMastershipStore store;
+    MastershipStoreDelegate storeDelegate;
+
+    private NodeId localNodeId;
+    private Timer requestRoleTimer;
+
+    /**
+     * Creates a new VirtualNetworkMastershipManager object.
+     *
+     * @param manager virtual network manager service
+     * @param networkId virtual network identifier
+     */
+    public VirtualNetworkMastershipManager(VirtualNetworkService manager, NetworkId networkId) {
+        super(manager, networkId, MastershipEvent.class);
+
+        clusterService = serviceDirectory.get(ClusterService.class);
+
+        store = serviceDirectory.get(VirtualNetworkMastershipStore.class);
+        this.storeDelegate = new InternalDelegate();
+        store.setDelegate(networkId, this.storeDelegate);
+
+        requestRoleTimer = createTimer("Virtual-mastership", "requestRole", "responseTime");
+        localNodeId = clusterService.getLocalNode().id();
+    }
+
+    @Override
+    public CompletableFuture<Void> setRole(NodeId nodeId, DeviceId deviceId,
+                                           MastershipRole role) {
+        checkNotNull(nodeId, NODE_ID_NULL);
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+        checkNotNull(role, ROLE_NULL);
+
+        CompletableFuture<MastershipEvent> eventFuture = null;
+
+        switch (role) {
+            case MASTER:
+                eventFuture = store.setMaster(networkId, nodeId, deviceId);
+                break;
+            case STANDBY:
+                eventFuture = store.setStandby(networkId, nodeId, deviceId);
+                break;
+            case NONE:
+                eventFuture = store.relinquishRole(networkId, nodeId, deviceId);
+                break;
+            default:
+                log.info("Unknown role; ignoring");
+                return CompletableFuture.completedFuture(null);
+        }
+
+        return eventFuture.thenAccept(this::post).thenApply(v -> null);
+    }
+
+    @Override
+    public MastershipRole getLocalRole(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+
+        return store.getRole(networkId, localNodeId, deviceId);
+    }
+
+    @Override
+    public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+
+        final Timer.Context timer = startTimer(requestRoleTimer);
+        return store.requestRole(networkId, deviceId)
+                .whenComplete((result, error) -> stopTimer(timer));
+    }
+
+    @Override
+    public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
+        return store.relinquishRole(networkId, localNodeId, deviceId)
+                .thenAccept(this::post)
+                .thenApply(v -> null);
+    }
+
+    @Override
+    public NodeId getMasterFor(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+
+        return store.getMaster(networkId, deviceId);
+    }
+
+    @Override
+    public RoleInfo getNodesFor(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+
+        return store.getNodes(networkId, deviceId);
+    }
+
+    @Override
+    public MastershipInfo getMastershipFor(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+        return store.getMastership(networkId, deviceId);
+    }
+
+    @Override
+    public Set<DeviceId> getDevicesOf(NodeId nodeId) {
+        checkNotNull(nodeId, NODE_ID_NULL);
+
+        return store.getDevices(networkId, nodeId);
+    }
+
+    @Override
+    public MastershipTerm getMastershipTerm(DeviceId deviceId) {
+        return store.getTermFor(networkId, deviceId);
+    }
+
+    @Override
+    public MetricsService metricsService() {
+        //TODO: support metric service for virtual network
+        log.warn("Currently, virtual network does not support metric service.");
+        return null;
+    }
+
+    @Override
+    public void balanceRoles() {
+        //FIXME: More advanced logic for balancing virtual network roles.
+        List<ControllerNode> nodes = clusterService.getNodes().stream()
+                .filter(n -> clusterService.getState(n.id())
+                        .equals(ControllerNode.State.ACTIVE))
+                .collect(Collectors.toList());
+
+        nodes.sort(Comparator.comparing(ControllerNode::id));
+
+        //Pick a node using network Id,
+        NodeId masterNode = nodes.get((int) ((networkId.id() - 1) % nodes.size())).id();
+
+        List<CompletableFuture<Void>> setRoleFutures = Lists.newLinkedList();
+        for (VirtualDevice device : manager.getVirtualDevices(networkId)) {
+            setRoleFutures.add(setRole(masterNode, device.id(), MastershipRole.MASTER));
+        }
+
+        CompletableFuture<Void> balanceRolesFuture = CompletableFuture.allOf(
+                setRoleFutures.toArray(new CompletableFuture[setRoleFutures.size()]));
+
+        Futures.getUnchecked(balanceRolesFuture);
+    }
+
+    public class InternalDelegate implements MastershipStoreDelegate {
+        @Override
+        public void notify(MastershipEvent event) {
+            post(event);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMeterManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMeterManager.java
new file mode 100644
index 0000000..2cce14c
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMeterManager.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright 2018-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.Maps;
+import org.apache.commons.lang3.tuple.Pair;
+import org.onlab.util.TriConsumer;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkMeterStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualMeterProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualMeterProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.DefaultMeter;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterEvent;
+import org.onosproject.net.meter.MeterFailReason;
+import org.onosproject.net.meter.MeterFeatures;
+import org.onosproject.net.meter.MeterFeaturesKey;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.meter.MeterKey;
+import org.onosproject.net.meter.MeterListener;
+import org.onosproject.net.meter.MeterOperation;
+import org.onosproject.net.meter.MeterRequest;
+import org.onosproject.net.meter.MeterService;
+import org.onosproject.net.meter.MeterState;
+import org.onosproject.net.meter.MeterStoreDelegate;
+import org.onosproject.net.meter.MeterStoreResult;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.AtomicCounter;
+import org.onosproject.store.service.StorageService;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class VirtualNetworkMeterManager
+        extends AbstractVirtualListenerManager<MeterEvent, MeterListener>
+        implements MeterService {
+
+    private static final String METERCOUNTERIDENTIFIER = "meter-id-counter-%s";
+    private final Logger log = getLogger(getClass());
+
+    protected StorageService coreStorageService;
+
+    protected VirtualNetworkMeterStore store;
+    private final MeterStoreDelegate storeDelegate = new InternalMeterStoreDelegate();
+
+    private VirtualProviderRegistryService providerRegistryService;
+    private InternalMeterProviderService innerProviderService;
+
+    private Map<DeviceId, AtomicCounter> meterIdCounters
+            = Maps.newConcurrentMap();
+
+    private TriConsumer<MeterRequest, MeterStoreResult, Throwable> onComplete;
+
+    /**
+     * Creates a new VirtualNetworkMeterManager object.
+     *
+     * @param manager virtual network manager service
+     * @param networkId a virtual network identifier
+     */
+    public VirtualNetworkMeterManager(VirtualNetworkService manager,
+                                      NetworkId networkId) {
+        super(manager, networkId, MeterEvent.class);
+
+        coreStorageService = serviceDirectory.get(StorageService.class);
+        providerRegistryService =
+                serviceDirectory.get(VirtualProviderRegistryService.class);
+
+        store = serviceDirectory.get(VirtualNetworkMeterStore.class);
+        store.setDelegate(networkId, this.storeDelegate);
+
+        innerProviderService = new InternalMeterProviderService();
+        providerRegistryService.registerProviderService(networkId(), innerProviderService);
+
+
+        onComplete = (request, result, error) -> {
+            request.context().ifPresent(c -> {
+                if (error != null) {
+                    c.onError(request, MeterFailReason.UNKNOWN);
+                } else {
+                    if (result.reason().isPresent()) {
+                        c.onError(request, result.reason().get());
+                    } else {
+                        c.onSuccess(request);
+                    }
+                }
+            });
+
+        };
+
+        log.info("Started");
+    }
+
+    @Override
+    public Meter submit(MeterRequest request) {
+
+        MeterId id = allocateMeterId(request.deviceId());
+
+        Meter.Builder mBuilder = DefaultMeter.builder()
+                .forDevice(request.deviceId())
+                .fromApp(request.appId())
+                .withBands(request.bands())
+                .withId(id)
+                .withUnit(request.unit());
+
+        if (request.isBurst()) {
+            mBuilder.burst();
+        }
+        DefaultMeter m = (DefaultMeter) mBuilder.build();
+        m.setState(MeterState.PENDING_ADD);
+        store.storeMeter(networkId(), m).whenComplete((result, error) ->
+                                                 onComplete.accept(request, result, error));
+        return m;
+    }
+
+    @Override
+    public void withdraw(MeterRequest request, MeterId meterId) {
+        Meter.Builder mBuilder = DefaultMeter.builder()
+                .forDevice(request.deviceId())
+                .fromApp(request.appId())
+                .withBands(request.bands())
+                .withId(meterId)
+                .withUnit(request.unit());
+
+        if (request.isBurst()) {
+            mBuilder.burst();
+        }
+
+        DefaultMeter m = (DefaultMeter) mBuilder.build();
+        m.setState(MeterState.PENDING_REMOVE);
+        store.deleteMeter(networkId(), m).whenComplete((result, error) ->
+                                                  onComplete.accept(request, result, error));
+    }
+
+    @Override
+    public Meter getMeter(DeviceId deviceId, MeterId id) {
+        MeterKey key = MeterKey.key(deviceId, id);
+        return store.getMeter(networkId(), key);
+    }
+
+    @Override
+    public Collection<Meter> getMeters(DeviceId deviceId) {
+        return store.getAllMeters(networkId()).stream()
+                .filter(m -> m.deviceId().equals(deviceId)).collect(Collectors.toList());
+    }
+
+    @Override
+    public Collection<Meter> getAllMeters() {
+        return store.getAllMeters(networkId());
+    }
+
+    private long queryMeters(DeviceId device) {
+        //FIXME: how to decide maximum number of meters per virtual device?
+        return 1;
+    }
+
+    private AtomicCounter allocateCounter(DeviceId deviceId) {
+        return coreStorageService
+                .getAtomicCounter(String.format(METERCOUNTERIDENTIFIER, deviceId));
+    }
+
+    public MeterId allocateMeterId(DeviceId deviceId) {
+        long maxMeters = store.getMaxMeters(networkId(), MeterFeaturesKey.key(deviceId));
+        if (maxMeters == 0L) {
+            // MeterFeatures couldn't be retrieved, trying with queryMeters
+            maxMeters = queryMeters(deviceId);
+        }
+
+        if (maxMeters == 0L) {
+            throw new IllegalStateException("Meters not supported by device " + deviceId);
+        }
+
+        final long mmeters = maxMeters;
+        long id = meterIdCounters.compute(deviceId, (k, v) -> {
+            if (v == null) {
+                return allocateCounter(k);
+            }
+            if (v.get() >= mmeters) {
+                throw new IllegalStateException("Maximum number of meters " +
+                                                        meterIdCounters.get(deviceId).get() +
+                                                        " reached for device " + deviceId +
+                                                        " virtual network " + networkId());
+            }
+            return v;
+        }).incrementAndGet();
+
+        return MeterId.meterId(id);
+    }
+
+    @Override
+    public void freeMeterId(DeviceId deviceId, MeterId meterId) {
+        // Do nothing
+    }
+
+    private class InternalMeterProviderService
+            extends AbstractVirtualProviderService<VirtualMeterProvider>
+            implements VirtualMeterProviderService {
+
+        /**
+         * Creates a provider service on behalf of the specified provider.
+         */
+        protected InternalMeterProviderService() {
+            Set<ProviderId> providerIds =
+                    providerRegistryService.getProvidersByService(this);
+            ProviderId providerId = providerIds.stream().findFirst().get();
+            VirtualMeterProvider provider = (VirtualMeterProvider)
+                    providerRegistryService.getProvider(providerId);
+            setProvider(provider);
+        }
+
+        @Override
+        public void meterOperationFailed(MeterOperation operation,
+                                         MeterFailReason reason) {
+            store.failedMeter(networkId(), operation, reason);
+        }
+
+        @Override
+        public void pushMeterMetrics(DeviceId deviceId, Collection<Meter> meterEntries) {
+            //FIXME: FOLLOWING CODE CANNOT BE TESTED UNTIL SOMETHING THAT
+            //FIXME: IMPLEMENTS METERS EXISTS
+            Map<Pair<DeviceId, MeterId>, Meter> storedMeterMap =
+                    store.getAllMeters(networkId()).stream()
+                    .collect(Collectors.toMap(m -> Pair.of(m.deviceId(), m.id()), Function.identity()));
+
+            meterEntries.stream()
+                    .filter(m -> storedMeterMap.remove(Pair.of(m.deviceId(), m.id())) != null)
+                    .forEach(m -> store.updateMeterState(networkId(), m));
+
+            storedMeterMap.values().forEach(m -> {
+                if (m.state() == MeterState.PENDING_ADD) {
+                    provider().performMeterOperation(networkId(), m.deviceId(),
+                                                     new MeterOperation(m,
+                                                                        MeterOperation.Type.MODIFY));
+                } else if (m.state() == MeterState.PENDING_REMOVE) {
+                    store.deleteMeterNow(networkId(), m);
+                }
+            });
+        }
+
+        @Override
+        public void pushMeterFeatures(DeviceId deviceId, MeterFeatures meterfeatures) {
+            store.storeMeterFeatures(networkId(), meterfeatures);
+        }
+
+        @Override
+        public void deleteMeterFeatures(DeviceId deviceId) {
+            store.deleteMeterFeatures(networkId(), deviceId);
+        }
+    }
+
+    private class InternalMeterStoreDelegate implements MeterStoreDelegate {
+
+        @Override
+        public void notify(MeterEvent event) {
+            DeviceId deviceId = event.subject().deviceId();
+            VirtualMeterProvider p = innerProviderService.provider();
+
+            switch (event.type()) {
+                case METER_ADD_REQ:
+                    p.performMeterOperation(networkId(), deviceId,
+                                            new MeterOperation(event.subject(),
+                                                               MeterOperation.Type.ADD));
+                    break;
+                case METER_REM_REQ:
+                    p.performMeterOperation(networkId(), deviceId,
+                                            new MeterOperation(event.subject(),
+                                                               MeterOperation.Type.REMOVE));
+                    break;
+                default:
+                    log.warn("Unknown meter event {}", event.type());
+            }
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManager.java
new file mode 100644
index 0000000..d1869ce
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManager.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2018-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.ImmutableList;
+import com.google.common.collect.Lists;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.virtual.AbstractVnetService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkPacketStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+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.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.packet.DefaultPacketRequest;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketEvent;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketProcessorEntry;
+import org.onosproject.net.packet.PacketRequest;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.packet.PacketStoreDelegate;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+public class VirtualNetworkPacketManager extends AbstractVnetService
+        implements PacketService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private final VirtualNetworkService manager;
+
+    protected VirtualNetworkPacketStore store;
+    private final List<ProcessorEntry> processors = Lists.newCopyOnWriteArrayList();
+
+    private NodeId localNodeId;
+
+    private DeviceService deviceService;
+    private FlowObjectiveService objectiveService;
+
+    private VirtualProviderRegistryService providerRegistryService = null;
+
+    private InternalPacketProviderService providerService = null;
+
+    public VirtualNetworkPacketManager(VirtualNetworkService virtualNetworkManager,
+                                       NetworkId networkId) {
+        super(virtualNetworkManager, networkId);
+        this.manager = virtualNetworkManager;
+
+        //Set node id as same as the node hosting virtual manager
+        ClusterService clusterService = serviceDirectory.get(ClusterService.class);
+        this.localNodeId = clusterService.getLocalNode().id();
+
+        this.store = serviceDirectory.get(VirtualNetworkPacketStore.class);
+        this.store.setDelegate(networkId(), new InternalStoreDelegate());
+
+        this.deviceService = manager.get(networkId(), DeviceService.class);
+        this.objectiveService = manager.get(networkId(), FlowObjectiveService.class);
+
+        providerRegistryService =
+                serviceDirectory.get(VirtualProviderRegistryService.class);
+        providerService = new InternalPacketProviderService();
+        providerRegistryService.registerProviderService(networkId(), providerService);
+    }
+
+    @Override
+    public void addProcessor(PacketProcessor processor, int priority) {
+        ProcessorEntry entry = new ProcessorEntry(processor, priority);
+
+        // Insert the new processor according to its priority.
+        int i = 0;
+        for (; i < processors.size(); i++) {
+            if (priority < processors.get(i).priority()) {
+                break;
+            }
+        }
+        processors.add(i, entry);
+    }
+
+    @Override
+    public void removeProcessor(PacketProcessor processor) {
+        // Remove the processor entry.
+        for (int i = 0; i < processors.size(); i++) {
+            if (processors.get(i).processor() == processor) {
+                processors.remove(i);
+                break;
+            }
+        }
+    }
+
+    @Override
+    public List<PacketProcessorEntry> getProcessors() {
+        return ImmutableList.copyOf(processors);
+    }
+
+    @Override
+    public void requestPackets(TrafficSelector selector, PacketPriority priority, ApplicationId appId) {
+        PacketRequest request = new DefaultPacketRequest(selector, priority, appId,
+                                                         localNodeId, Optional.empty());
+        store.requestPackets(networkId(), request);
+    }
+
+    @Override
+    public void requestPackets(TrafficSelector selector, PacketPriority priority,
+                               ApplicationId appId, Optional<DeviceId> deviceId) {
+        PacketRequest request =
+                new DefaultPacketRequest(selector, priority, appId,
+                                         localNodeId, deviceId);
+
+        store.requestPackets(networkId(), request);
+    }
+
+    @Override
+    public void cancelPackets(TrafficSelector selector, PacketPriority priority, ApplicationId appId) {
+        PacketRequest request = new DefaultPacketRequest(selector, priority, appId,
+                                                         localNodeId, Optional.empty());
+        store.cancelPackets(networkId(), request);
+    }
+
+    @Override
+    public void cancelPackets(TrafficSelector selector, PacketPriority priority,
+                              ApplicationId appId, Optional<DeviceId> deviceId) {
+        PacketRequest request = new DefaultPacketRequest(selector, priority,
+                                                         appId, localNodeId,
+                                                         deviceId);
+        store.cancelPackets(networkId(), request);
+    }
+
+    @Override
+    public List<PacketRequest> getRequests() {
+        return store.existingRequests(networkId());
+    }
+
+    @Override
+    public void emit(OutboundPacket packet) {
+        store.emit(networkId(), packet);
+    }
+
+    /**
+     * Personalized packet provider service issued to the supplied provider.
+     */
+    private class InternalPacketProviderService
+            extends AbstractVirtualProviderService<VirtualPacketProvider>
+            implements VirtualPacketProviderService {
+
+        protected InternalPacketProviderService() {
+            super();
+
+            Set<ProviderId> providerIds =
+                    providerRegistryService.getProvidersByService(this);
+            ProviderId providerId = providerIds.stream().findFirst().get();
+            VirtualPacketProvider provider = (VirtualPacketProvider)
+                    providerRegistryService.getProvider(providerId);
+            setProvider(provider);
+        }
+
+        @Override
+        public void processPacket(PacketContext context) {
+            // TODO filter packets sent to processors based on registrations
+            for (ProcessorEntry entry : processors) {
+                try {
+                    long start = System.nanoTime();
+                    entry.processor().process(context);
+                    entry.addNanos(System.nanoTime() - start);
+                } catch (Exception e) {
+                    log.warn("Packet processor {} threw an exception", entry.processor(), e);
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Entity for tracking stats for a packet processor.
+     */
+    private class ProcessorEntry implements PacketProcessorEntry {
+        private final PacketProcessor processor;
+        private final int priority;
+        private long invocations = 0;
+        private long nanos = 0;
+
+        public ProcessorEntry(PacketProcessor processor, int priority) {
+            this.processor = processor;
+            this.priority = priority;
+        }
+
+        @Override
+        public PacketProcessor processor() {
+            return processor;
+        }
+
+        @Override
+        public int priority() {
+            return priority;
+        }
+
+        @Override
+        public long invocations() {
+            return invocations;
+        }
+
+        @Override
+        public long totalNanos() {
+            return nanos;
+        }
+
+        @Override
+        public long averageNanos() {
+            return invocations > 0 ? nanos / invocations : 0;
+        }
+
+        void addNanos(long nanos) {
+            this.nanos += nanos;
+            this.invocations++;
+        }
+    }
+
+    private void localEmit(NetworkId networkId, OutboundPacket packet) {
+        Device device = deviceService.getDevice(packet.sendThrough());
+        if (device == null) {
+            return;
+        }
+        VirtualPacketProvider packetProvider = providerService.provider();
+
+        if (packetProvider != null) {
+            packetProvider.emit(networkId, packet);
+        }
+    }
+
+    /**
+     * Internal callback from the packet store.
+     */
+    protected class InternalStoreDelegate implements PacketStoreDelegate {
+        @Override
+        public void notify(PacketEvent event) {
+            localEmit(networkId(), event.subject());
+        }
+
+        @Override
+        public void requestPackets(PacketRequest request) {
+            DeviceId deviceid = request.deviceId().orElse(null);
+
+            if (deviceid != null) {
+                pushRule(deviceService.getDevice(deviceid), request);
+            } else {
+                pushToAllDevices(request);
+            }
+        }
+
+        @Override
+        public void cancelPackets(PacketRequest request) {
+            DeviceId deviceid = request.deviceId().orElse(null);
+
+            if (deviceid != null) {
+                removeRule(deviceService.getDevice(deviceid), request);
+            } else {
+                removeFromAllDevices(request);
+            }
+        }
+    }
+
+    /**
+     * Pushes packet intercept flow rules to the device.
+     *
+     * @param device  the device to push the rules to
+     * @param request the packet request
+     */
+    private void pushRule(Device device, PacketRequest request) {
+        if (!device.type().equals(Device.Type.VIRTUAL)) {
+            return;
+        }
+
+        ForwardingObjective forwarding = createBuilder(request)
+                .add(new ObjectiveContext() {
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.warn("Failed to install packet request {} to {}: {}",
+                                 request, device.id(), error);
+                    }
+                });
+
+        objectiveService.forward(device.id(), forwarding);
+    }
+
+    /**
+     * Removes packet intercept flow rules from the device.
+     *
+     * @param device  the device to remove the rules deom
+     * @param request the packet request
+     */
+    private void removeRule(Device device, PacketRequest request) {
+        if (!device.type().equals(Device.Type.VIRTUAL)) {
+            return;
+        }
+        ForwardingObjective forwarding = createBuilder(request)
+                .remove(new ObjectiveContext() {
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.warn("Failed to withdraw packet request {} from {}: {}",
+                                 request, device.id(), error);
+                    }
+                });
+        objectiveService.forward(device.id(), forwarding);
+    }
+
+    /**
+     * Pushes a packet request flow rule to all devices.
+     *
+     * @param request the packet request
+     */
+    private void pushToAllDevices(PacketRequest request) {
+        log.debug("Pushing packet request {} to all devices", request);
+        for (Device device : deviceService.getDevices()) {
+            pushRule(device, request);
+        }
+    }
+
+    /**
+     * Removes packet request flow rule from all devices.
+     *
+     * @param request the packet request
+     */
+    private void removeFromAllDevices(PacketRequest request) {
+        deviceService.getAvailableDevices().forEach(d -> removeRule(d, request));
+    }
+
+    private DefaultForwardingObjective.Builder createBuilder(PacketRequest request) {
+        return DefaultForwardingObjective.builder()
+                .withPriority(request.priority().priorityValue())
+                .withSelector(request.selector())
+                .fromApp(request.appId())
+                .withFlag(ForwardingObjective.Flag.VERSATILE)
+                .withTreatment(DefaultTrafficTreatment.builder().punt().build())
+                .makePermanent();
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManager.java
new file mode 100644
index 0000000..de0dffa
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManager.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2018-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 org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VnetService;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.ElementId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.topology.LinkWeigher;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.net.topology.AbstractPathService;
+import org.onosproject.net.topology.TopologyService;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Path service implementation built on the virtual network service.
+ */
+public class VirtualNetworkPathManager
+        extends AbstractPathService
+        implements PathService, VnetService {
+
+    private final NetworkId networkId;
+
+    /**
+     * Creates a new virtual network path service object.
+     *
+     * @param virtualNetworkManager virtual network manager service
+     * @param networkId a virtual network identifier
+     */
+
+    public VirtualNetworkPathManager(VirtualNetworkService virtualNetworkManager,
+                                     NetworkId networkId) {
+        this.networkId = networkId;
+
+        topologyService = virtualNetworkManager.get(networkId(), TopologyService.class);
+        hostService = virtualNetworkManager.get(networkId(), HostService.class);
+    }
+
+    @Override
+    public Set<Path> getPaths(ElementId src, ElementId dst) {
+        return super.getPaths(src, dst, (LinkWeigher) null);
+    }
+
+    @Override
+    public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst) {
+        return getDisjointPaths(src, dst, (LinkWeigher) null);
+    }
+
+    @Override
+    public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst,
+                                              Map<Link, Object> riskProfile) {
+        return getDisjointPaths(src, dst, (LinkWeigher) null, riskProfile);
+    }
+
+    @Override
+    public NetworkId networkId() {
+        return this.networkId;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManager.java
new file mode 100644
index 0000000..aad3ac4
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManager.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2018-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 org.onosproject.common.DefaultTopology;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.topology.ClusterId;
+import org.onosproject.net.topology.DefaultGraphDescription;
+import org.onosproject.net.topology.LinkWeigher;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyCluster;
+import org.onosproject.net.topology.TopologyEvent;
+import org.onosproject.net.topology.TopologyGraph;
+import org.onosproject.net.topology.TopologyListener;
+import org.onosproject.net.topology.TopologyService;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.incubator.net.virtual.DefaultVirtualLink.PID;
+
+/**
+ * Topology service implementation built on the virtual network service.
+ */
+public class VirtualNetworkTopologyManager
+        extends AbstractVirtualListenerManager<TopologyEvent, TopologyListener>
+        implements TopologyService {
+
+    private static final String TOPOLOGY_NULL = "Topology cannot be null";
+    private static final String DEVICE_ID_NULL = "Device ID cannot be null";
+    private static final String CLUSTER_ID_NULL = "Cluster ID cannot be null";
+    private static final String CLUSTER_NULL = "Topology cluster cannot be null";
+    private static final String CONNECTION_POINT_NULL = "Connection point cannot be null";
+    private static final String LINK_WEIGHT_NULL = "Link weight cannot be null";
+
+    /**
+     * Creates a new VirtualNetworkTopologyService object.
+     *
+     * @param virtualNetworkManager virtual network manager service
+     * @param networkId a virtual network identifier
+     */
+    public VirtualNetworkTopologyManager(VirtualNetworkService virtualNetworkManager,
+                                         NetworkId networkId) {
+        super(virtualNetworkManager, networkId, TopologyEvent.class);
+    }
+
+    @Override
+    public Topology currentTopology() {
+        Iterable<Device> devices = manager.getVirtualDevices(networkId())
+                .stream()
+                .collect(Collectors.toSet());
+        Iterable<Link> links = manager.getVirtualLinks(networkId())
+                .stream()
+                .collect(Collectors.toSet());
+
+        DefaultGraphDescription graph =
+                new DefaultGraphDescription(System.nanoTime(),
+                                            System.currentTimeMillis(),
+                                            devices, links);
+        return new DefaultTopology(PID, graph);
+    }
+
+    @Override
+    public boolean isLatest(Topology topology) {
+        Topology currentTopology = currentTopology();
+        return defaultTopology(topology).getGraph()
+                .equals(defaultTopology(currentTopology).getGraph());
+    }
+
+    @Override
+    public TopologyGraph getGraph(Topology topology) {
+        return defaultTopology(topology).getGraph();
+    }
+
+    // Validates the specified topology and returns it as a default
+    private DefaultTopology defaultTopology(Topology topology) {
+        checkNotNull(topology, TOPOLOGY_NULL);
+        checkArgument(topology instanceof DefaultTopology,
+                      "Topology class %s not supported", topology.getClass());
+        return (DefaultTopology) topology;
+    }
+
+    @Override
+    public Set<TopologyCluster> getClusters(Topology topology) {
+        return defaultTopology(topology).getClusters();
+    }
+
+    @Override
+    public TopologyCluster getCluster(Topology topology, ClusterId clusterId) {
+        checkNotNull(clusterId, CLUSTER_ID_NULL);
+        return defaultTopology(topology).getCluster(clusterId);
+    }
+
+    @Override
+    public Set<DeviceId> getClusterDevices(Topology topology, TopologyCluster cluster) {
+        checkNotNull(cluster, CLUSTER_NULL);
+        return defaultTopology(topology).getClusterDevices(cluster);
+    }
+
+    @Override
+    public Set<Link> getClusterLinks(Topology topology, TopologyCluster cluster) {
+        checkNotNull(cluster, CLUSTER_NULL);
+        return defaultTopology(topology).getClusterLinks(cluster);
+    }
+
+    @Override
+    public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst) {
+        checkNotNull(src, DEVICE_ID_NULL);
+        checkNotNull(dst, DEVICE_ID_NULL);
+        return defaultTopology(topology).getPaths(src, dst);
+    }
+
+    @Override
+    public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst,
+                              LinkWeigher weigher) {
+        checkNotNull(src, DEVICE_ID_NULL);
+        checkNotNull(dst, DEVICE_ID_NULL);
+        checkNotNull(weigher, LINK_WEIGHT_NULL);
+        return defaultTopology(topology).getPaths(src, dst, weigher);
+    }
+
+    @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
+                                              DeviceId dst) {
+        checkNotNull(src, DEVICE_ID_NULL);
+        checkNotNull(dst, DEVICE_ID_NULL);
+        return defaultTopology(topology).getDisjointPaths(src, dst);
+    }
+
+    @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
+                                              DeviceId dst,
+                                              LinkWeigher weigher) {
+        checkNotNull(src, DEVICE_ID_NULL);
+        checkNotNull(dst, DEVICE_ID_NULL);
+        checkNotNull(weigher, LINK_WEIGHT_NULL);
+        return defaultTopology(topology).getDisjointPaths(src, dst, weigher);
+    }
+
+    @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
+                                              DeviceId dst,
+                                              Map<Link, Object> riskProfile) {
+        checkNotNull(src, DEVICE_ID_NULL);
+        checkNotNull(dst, DEVICE_ID_NULL);
+        return defaultTopology(topology).getDisjointPaths(src, dst, riskProfile);
+    }
+
+    @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
+                                              DeviceId dst,
+                                              LinkWeigher weigher,
+                                              Map<Link, Object> riskProfile) {
+        checkNotNull(src, DEVICE_ID_NULL);
+        checkNotNull(dst, DEVICE_ID_NULL);
+        checkNotNull(weigher, LINK_WEIGHT_NULL);
+        return defaultTopology(topology).getDisjointPaths(src, dst, weigher,
+                riskProfile);
+    }
+
+    @Override
+    public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) {
+        checkNotNull(connectPoint, CONNECTION_POINT_NULL);
+        return defaultTopology(topology).isInfrastructure(connectPoint);
+    }
+
+    @Override
+    public boolean isBroadcastPoint(Topology topology, ConnectPoint connectPoint) {
+        checkNotNull(connectPoint, CONNECTION_POINT_NULL);
+        return defaultTopology(topology).isBroadcastPoint(connectPoint);
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentAccumulator.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentAccumulator.java
new file mode 100644
index 0000000..0328383
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentAccumulator.java
@@ -0,0 +1,82 @@
+/*
+ * 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.intent;
+
+import com.google.common.collect.Maps;
+import org.onlab.util.AbstractAccumulator;
+import org.onosproject.net.intent.IntentBatchDelegate;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.Key;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+
+/**
+ * An accumulator for building batches of intent operations for virtual network.
+ * Only one batch should be in process per instance at a time.
+ */
+public class VirtualIntentAccumulator extends AbstractAccumulator<IntentData> {
+    private static final int DEFAULT_MAX_EVENTS = 1000;
+    private static final int DEFAULT_MAX_IDLE_MS = 10;
+    private static final int DEFAULT_MAX_BATCH_MS = 50;
+
+    // FIXME: Replace with a system-wide timer instance;
+    // TODO: Convert to use HashedWheelTimer or produce a variant of that; then decide which we want to adopt
+    private static final Timer TIMER = new Timer("virtual-intent-op-batching");
+
+    private final IntentBatchDelegate delegate;
+
+    private volatile boolean ready;
+
+    /**
+     * Creates an intent operation accumulator.
+     *
+     * @param delegate the intent batch delegate
+     */
+    public VirtualIntentAccumulator(IntentBatchDelegate delegate) {
+        super(TIMER, DEFAULT_MAX_EVENTS, DEFAULT_MAX_BATCH_MS, DEFAULT_MAX_IDLE_MS);
+        this.delegate = delegate;
+        // Assume that the delegate is ready for work at the start
+        ready = true; //TODO validate the assumption that delegate is ready
+    }
+
+    @Override
+    public void processItems(List<IntentData> items) {
+        ready = false;
+        delegate.execute(reduce(items));
+    }
+
+    private Collection<IntentData> reduce(List<IntentData> ops) {
+        Map<Key, IntentData> map = Maps.newHashMap();
+        for (IntentData op : ops) {
+            map.put(op.key(), op);
+        }
+        //TODO check the version... or maybe store will handle this.
+        return map.values();
+    }
+
+    @Override
+    public boolean isReady() {
+        return ready;
+    }
+
+    public void ready() {
+        ready = true;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentCompilerRegistry.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentCompilerRegistry.java
new file mode 100644
index 0000000..f922c22
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentCompilerRegistry.java
@@ -0,0 +1,170 @@
+/*
+ * 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.intent;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.intent.VirtualIntentCompiler;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentException;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+public final class VirtualIntentCompilerRegistry {
+    private final ConcurrentMap<Class<? extends Intent>,
+                VirtualIntentCompiler<? extends Intent>> compilers = new ConcurrentHashMap<>();
+
+    // non-instantiable (except for our Singleton)
+    private VirtualIntentCompilerRegistry() {
+
+    }
+
+    public static VirtualIntentCompilerRegistry getInstance() {
+        return SingletonHelper.INSTANCE;
+    }
+
+    /**
+     * Registers the specified compiler for the given intent class.
+     *
+     * @param cls      intent class
+     * @param compiler intent compiler
+     * @param <T>      the type of intent
+     */
+    public <T extends Intent> void registerCompiler(Class<T> cls,
+                                                    VirtualIntentCompiler<T> compiler) {
+        compilers.put(cls, compiler);
+    }
+
+    /**
+     * Unregisters the compiler for the specified intent class.
+     *
+     * @param cls intent class
+     * @param <T> the type of intent
+     */
+    public <T extends Intent> void unregisterCompiler(Class<T> cls) {
+        compilers.remove(cls);
+    }
+
+    /**
+     * Returns immutable set of bindings of currently registered intent compilers.
+     *
+     * @return the set of compiler bindings
+     */
+    public Map<Class<? extends Intent>, VirtualIntentCompiler<? extends Intent>> getCompilers() {
+        return ImmutableMap.copyOf(compilers);
+    }
+
+    /**
+     * Compiles an intent recursively.
+     *
+     * @param networkId network identifier
+     * @param intent intent
+     * @param previousInstallables previous intent installables
+     * @return result of compilation
+     */
+    public List<Intent> compile(NetworkId networkId,
+                         Intent intent, List<Intent> previousInstallables) {
+        if (intent.isInstallable()) {
+            return ImmutableList.of(intent);
+        }
+
+        // FIXME: get previous resources
+        List<Intent> installables = new ArrayList<>();
+        Queue<Intent> compileQueue = new LinkedList<>();
+        compileQueue.add(intent);
+
+        Intent compiling;
+        while ((compiling = compileQueue.poll()) != null) {
+            registerSubclassCompilerIfNeeded(compiling);
+
+            List<Intent> compiled = getCompiler(compiling)
+                    .compile(networkId, compiling, previousInstallables);
+
+            compiled.forEach(i -> {
+                if (i.isInstallable()) {
+                    installables.add(i);
+                } else {
+                    compileQueue.add(i);
+                }
+            });
+        }
+        return installables;
+    }
+
+    /**
+     * Returns the corresponding intent compiler to the specified intent.
+     *
+     * @param intent intent
+     * @param <T>    the type of intent
+     * @return intent compiler corresponding to the specified intent
+     */
+    private <T extends Intent> VirtualIntentCompiler<T> getCompiler(T intent) {
+        @SuppressWarnings("unchecked")
+        VirtualIntentCompiler<T> compiler =
+                (VirtualIntentCompiler<T>) compilers.get(intent.getClass());
+        if (compiler == null) {
+            throw new IntentException("no compiler for class " + intent.getClass());
+        }
+        return compiler;
+    }
+
+    /**
+     * Registers an intent compiler of the specified intent if an intent compiler
+     * for the intent is not registered. This method traverses the class hierarchy of
+     * the intent. Once an intent compiler for a parent type is found, this method
+     * registers the found intent compiler.
+     *
+     * @param intent intent
+     */
+    private void registerSubclassCompilerIfNeeded(Intent intent) {
+        if (!compilers.containsKey(intent.getClass())) {
+            Class<?> cls = intent.getClass();
+            while (cls != Object.class) {
+                // As long as we're within the Intent class descendants
+                if (Intent.class.isAssignableFrom(cls)) {
+                    VirtualIntentCompiler<?> compiler = compilers.get(cls);
+                    if (compiler != null) {
+                        compilers.put(intent.getClass(), compiler);
+                        return;
+                    }
+                }
+                cls = cls.getSuperclass();
+            }
+        }
+    }
+
+    /**
+     * Prevents object instantiation from external.
+     */
+    private static final class SingletonHelper {
+        private static final String ILLEGAL_ACCESS_MSG =
+                "Should not instantiate this class.";
+        private static final VirtualIntentCompilerRegistry INSTANCE =
+                new VirtualIntentCompilerRegistry();
+
+        private SingletonHelper() {
+            throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentInstallCoordinator.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentInstallCoordinator.java
new file mode 100644
index 0000000..4a09250
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentInstallCoordinator.java
@@ -0,0 +1,226 @@
+/*
+ * 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.intent;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntentStore;
+import org.onosproject.incubator.net.virtual.impl.VirtualNetworkIntentManager;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentInstallationContext;
+import org.onosproject.net.intent.IntentInstaller;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.slf4j.Logger;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import static org.onosproject.net.intent.IntentState.*;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of IntentInstallCoordinator for virtual network.
+ */
+public class VirtualIntentInstallCoordinator {
+    private static final String INSTALLER_NOT_FOUND = "Intent installer not found, Intent: {}";
+    private final Logger log = getLogger(VirtualNetworkIntentManager.class);
+
+    NetworkId networkId;
+    private VirtualIntentInstallerRegistry installerRegistry;
+    private VirtualNetworkIntentStore intentStore;
+
+    /**
+     * Creates an InstallCoordinator.
+     *
+     * @param networkId virtual network identifier
+     * @param installerRegistry the installer registry
+     * @param intentStore the Intent store
+     */
+    public VirtualIntentInstallCoordinator(NetworkId networkId,
+                                           VirtualIntentInstallerRegistry installerRegistry,
+                                           VirtualNetworkIntentStore intentStore) {
+        this.networkId = networkId;
+        this.installerRegistry = installerRegistry;
+        this.intentStore = intentStore;
+    }
+
+    /**
+     * Applies Intent data to be uninstalled and to be installed.
+     *
+     * @param toUninstall Intent data to be uninstalled
+     * @param toInstall Intent data to be installed
+     */
+    public void installIntents(Optional<IntentData> toUninstall,
+                               Optional<IntentData> toInstall) {
+        // If no any Intents to be uninstalled or installed, ignore it.
+        if (!toUninstall.isPresent() && !toInstall.isPresent()) {
+            return;
+        }
+
+        // Classify installable Intents to different installers.
+        ArrayListMultimap<IntentInstaller, Intent> uninstallInstallers;
+        ArrayListMultimap<IntentInstaller, Intent> installInstallers;
+        Set<IntentInstaller> allInstallers = Sets.newHashSet();
+
+        if (toUninstall.isPresent()) {
+            uninstallInstallers = getInstallers(toUninstall.get());
+            allInstallers.addAll(uninstallInstallers.keySet());
+        } else {
+            uninstallInstallers = ArrayListMultimap.create();
+        }
+
+        if (toInstall.isPresent()) {
+            installInstallers = getInstallers(toInstall.get());
+            allInstallers.addAll(installInstallers.keySet());
+        } else {
+            installInstallers = ArrayListMultimap.create();
+        }
+
+        // Generates an installation context for the high level Intent.
+        IntentInstallationContext installationContext =
+                new IntentInstallationContext(toUninstall.orElse(null), toInstall.orElse(null));
+
+        //Generates different operation context for different installable Intents.
+        Map<IntentInstaller, IntentOperationContext> contexts = Maps.newHashMap();
+        allInstallers.forEach(installer -> {
+            List<Intent> intentsToUninstall = uninstallInstallers.get(installer);
+            List<Intent> intentsToInstall = installInstallers.get(installer);
+
+            // Connect context to high level installation context
+            IntentOperationContext context =
+                    new IntentOperationContext(intentsToUninstall, intentsToInstall,
+                                               installationContext);
+            installationContext.addPendingContext(context);
+            contexts.put(installer, context);
+        });
+
+        // Apply contexts to installers
+        contexts.forEach((installer, context) -> {
+            installer.apply(context);
+        });
+    }
+
+    /**
+     * Generates a mapping for installable Intents to installers.
+     *
+     * @param intentData the Intent data which contains installable Intents
+     * @return the mapping for installable Intents to installers
+     */
+    private ArrayListMultimap<IntentInstaller, Intent> getInstallers(IntentData intentData) {
+        ArrayListMultimap<IntentInstaller, Intent> intentInstallers = ArrayListMultimap.create();
+        intentData.installables().forEach(intent -> {
+            IntentInstaller installer = installerRegistry.getInstaller(intent.getClass());
+            if (installer != null) {
+                intentInstallers.put(installer, intent);
+            } else {
+                log.warn(INSTALLER_NOT_FOUND, intent);
+            }
+        });
+        return intentInstallers;
+    }
+
+    /**
+     * Handles success operation context.
+     *
+     * @param context the operation context
+     */
+    public void success(IntentOperationContext context) {
+        IntentInstallationContext intentInstallationContext =
+                context.intentInstallationContext();
+        intentInstallationContext.removePendingContext(context);
+
+        if (intentInstallationContext.isPendingContextsEmpty()) {
+            finish(intentInstallationContext);
+        }
+    }
+
+    /**
+     * Handles failed operation context.
+     *
+     * @param context the operation context
+     */
+    public void failed(IntentOperationContext context) {
+        IntentInstallationContext intentInstallationContext =
+                context.intentInstallationContext();
+        intentInstallationContext.addErrorContext(context);
+        intentInstallationContext.removePendingContext(context);
+
+        if (intentInstallationContext.isPendingContextsEmpty()) {
+            finish(intentInstallationContext);
+        }
+    }
+
+    /**
+     * Completed the installation context and update the Intent store.
+     *
+     * @param intentInstallationContext the installation context
+     */
+    private void finish(IntentInstallationContext intentInstallationContext) {
+        Set<IntentOperationContext> errCtxs = intentInstallationContext.errorContexts();
+        Optional<IntentData> toUninstall = intentInstallationContext.toUninstall();
+        Optional<IntentData> toInstall = intentInstallationContext.toInstall();
+
+        // Intent install success
+        if (errCtxs == null || errCtxs.isEmpty()) {
+            if (toInstall.isPresent()) {
+                IntentData installData = toInstall.get();
+                log.debug("Completed installing: {}", installData.key());
+                installData = new IntentData(installData, installData.installables());
+                installData.setState(INSTALLED);
+                intentStore.write(networkId, installData);
+            } else if (toUninstall.isPresent()) {
+                IntentData uninstallData = toUninstall.get();
+                uninstallData = new IntentData(uninstallData, Collections.emptyList());
+                log.debug("Completed withdrawing: {}", uninstallData.key());
+                switch (uninstallData.request()) {
+                    case INSTALL_REQ:
+                        log.warn("{} was requested to withdraw during installation?",
+                                 uninstallData.intent());
+                        uninstallData.setState(FAILED);
+                        break;
+                    case WITHDRAW_REQ:
+                    default: //TODO "default" case should not happen
+                        uninstallData.setState(WITHDRAWN);
+                        break;
+                }
+                // Intent has been withdrawn; we can clear the installables
+                intentStore.write(networkId, uninstallData);
+            }
+        } else {
+            // if toInstall was cause of error, then recompile (manage/increment counter, when exceeded -> CORRUPT)
+            if (toInstall.isPresent()) {
+                IntentData installData = toInstall.get();
+                installData.setState(CORRUPT);
+                installData.incrementErrorCount();
+                intentStore.write(networkId, installData);
+            }
+            // if toUninstall was cause of error, then CORRUPT (another job will clean this up)
+            if (toUninstall.isPresent()) {
+                IntentData uninstallData = toUninstall.get();
+                uninstallData.setState(CORRUPT);
+                uninstallData.incrementErrorCount();
+                intentStore.write(networkId, uninstallData);
+            }
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentInstallerRegistry.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentInstallerRegistry.java
new file mode 100644
index 0000000..a0e6448
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentInstallerRegistry.java
@@ -0,0 +1,96 @@
+/*
+ * 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.intent;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentInstaller;
+
+import java.util.Map;
+
+/**
+ * The local registry for Intent installer for virtual networks.
+ */
+public final class VirtualIntentInstallerRegistry {
+    private final Map<Class<? extends Intent>,
+                IntentInstaller<? extends Intent>> installers;
+
+    // non-instantiable (except for our Singleton)
+    private VirtualIntentInstallerRegistry() {
+        installers = Maps.newConcurrentMap();
+    }
+
+    public static VirtualIntentInstallerRegistry getInstance() {
+        return SingletonHelper.INSTANCE;
+    }
+
+    /**
+     * Registers the specific installer for the given intent class.
+     *
+     * @param cls intent class
+     * @param installer intent installer
+     * @param <T> the type of intent
+     */
+    public <T extends Intent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
+        installers.put(cls, installer);
+    }
+
+    /**
+     * Unregisters the installer for the specific intent class.
+     *
+     * @param cls intent class
+     * @param <T> the type of intent
+     */
+    public <T extends Intent> void unregisterInstaller(Class<T> cls) {
+        installers.remove(cls);
+    }
+
+    /**
+     * Returns immutable set of binding of currently registered intent installers.
+     *
+     * @return the set of installer bindings
+     */
+    public Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> getInstallers() {
+        return ImmutableMap.copyOf(installers);
+    }
+
+    /**
+     * Get an Intent installer by given Intent type.
+     *
+     * @param cls the Intent type
+     * @param <T> the Intent type
+     * @return the Intent installer of the Intent type if exists; null otherwise
+     */
+    public <T extends Intent> IntentInstaller<T> getInstaller(Class<T> cls) {
+        return (IntentInstaller<T>) installers.get(cls);
+    }
+
+    /**
+     * Prevents object instantiation from external.
+     */
+    private static final class SingletonHelper {
+        private static final String ILLEGAL_ACCESS_MSG =
+                "Should not instantiate this class.";
+        private static final VirtualIntentInstallerRegistry INSTANCE =
+                new VirtualIntentInstallerRegistry();
+
+        private SingletonHelper() {
+            throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentProcessor.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentProcessor.java
new file mode 100644
index 0000000..a7719f9
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentProcessor.java
@@ -0,0 +1,52 @@
+/*
+ * 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.intent;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * A collection of methods to process an intent for virtual networks.
+ *
+ * This interface is public, but intended to be used only by IntentManager and
+ * IntentProcessPhase subclasses stored under phase package.
+ */
+public interface VirtualIntentProcessor {
+    /**
+     * Compiles an intent recursively.
+     *
+     * @param networkId virtual network identifier
+     * @param intent intent
+     * @param previousInstallables previous intent installables
+     * @return result of compilation
+     */
+    List<Intent> compile(NetworkId networkId, Intent intent, List<Intent> previousInstallables);
+
+    /**
+     * Applies intents.
+     *
+     * @param networkId virtual network identifier
+     * @param toUninstall Intent data describing flows to uninstall.
+     * @param toInstall Intent data describing flows to install.
+     */
+    void apply(NetworkId networkId, Optional<IntentData> toUninstall,
+               Optional<IntentData> toInstall);
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentSkipped.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentSkipped.java
new file mode 100644
index 0000000..df7f451
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/VirtualIntentSkipped.java
@@ -0,0 +1,48 @@
+/*
+ * 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.intent;
+
+import org.onosproject.incubator.net.virtual.impl.intent.phase.VirtualFinalIntentProcessPhase;
+import org.onosproject.net.intent.IntentData;
+
+/**
+ * Represents a phase where an intent is not compiled for a virtual network.
+ * This should be used if a new version of the intent will immediately override
+ * this one.
+ */
+public final class VirtualIntentSkipped extends VirtualFinalIntentProcessPhase {
+
+    private static final VirtualIntentSkipped SINGLETON = new VirtualIntentSkipped();
+
+    /**
+     * Returns a shared skipped phase.
+     *
+     * @return skipped phase
+     */
+    public static VirtualIntentSkipped getPhase() {
+        return SINGLETON;
+    }
+
+    // Prevent object construction; use getPhase()
+    private VirtualIntentSkipped() {
+    }
+
+    @Override
+    public IntentData data() {
+        return null;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/package-info.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/package-info.java
new file mode 100644
index 0000000..c6758ae
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Core subsystem for tracking high-level intents for treatment of selected
+ * network traffic for virtual networks.
+ */
+package org.onosproject.incubator.net.virtual.impl.intent;
\ No newline at end of file
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualFinalIntentProcessPhase.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualFinalIntentProcessPhase.java
new file mode 100644
index 0000000..978c95c
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualFinalIntentProcessPhase.java
@@ -0,0 +1,46 @@
+/*
+ * 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.intent.phase;
+
+import org.onosproject.net.intent.IntentData;
+
+import java.util.Optional;
+
+/**
+ * Represents a final phase of processing an intent for virtual networks.
+ */
+public abstract class VirtualFinalIntentProcessPhase
+        implements VirtualIntentProcessPhase {
+
+    @Override
+    public final Optional<VirtualIntentProcessPhase> execute() {
+        preExecute();
+        return Optional.empty();
+    }
+
+    /**
+     * Executes operations that must take place before the phase starts.
+     */
+    protected void preExecute() {}
+
+    /**
+     * Returns the IntentData object being acted on by this phase.
+     *
+     * @return intent data object for the phase
+     */
+    public abstract IntentData data();
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentCompiling.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentCompiling.java
new file mode 100644
index 0000000..639c04c
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentCompiling.java
@@ -0,0 +1,81 @@
+/*
+ * 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.intent.phase;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentProcessor;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Represents a phase where an intent is being compiled or recompiled
+ * for virtual networks.
+ */
+public class VirtualIntentCompiling implements VirtualIntentProcessPhase {
+    private static final Logger log = LoggerFactory.getLogger(VirtualIntentCompiling.class);
+
+    private final NetworkId networkId;
+    private final VirtualIntentProcessor processor;
+    private final IntentData data;
+    private final Optional<IntentData> stored;
+
+    /**
+     * Creates a intent recompiling phase.
+     *
+     * @param networkId virtual network identifier
+     * @param processor intent processor that does work for recompiling
+     * @param data      intent data containing an intent to be recompiled
+     * @param stored    intent data stored in the store
+     */
+    VirtualIntentCompiling(NetworkId networkId, VirtualIntentProcessor processor,
+                           IntentData data, Optional<IntentData> stored) {
+        this.networkId = checkNotNull(networkId);
+        this.processor = checkNotNull(processor);
+        this.data = checkNotNull(data);
+        this.stored = checkNotNull(stored);
+    }
+
+    @Override
+    public Optional<VirtualIntentProcessPhase> execute() {
+        try {
+            List<Intent> compiled = processor
+                    .compile(networkId, data.intent(),
+                             //TODO consider passing an optional here in the future
+                             stored.map(IntentData::installables).orElse(null));
+            return Optional.of(new VirtualIntentInstalling(networkId, processor,
+                                                           IntentData.compiled(data, compiled), stored));
+        } catch (IntentException e) {
+            log.warn("Unable to compile intent {} due to:", data.intent(), e);
+            if (stored.filter(x -> !x.installables().isEmpty()).isPresent()) {
+                // removing orphaned flows and deallocating resources
+                return Optional.of(
+                        new VirtualIntentWithdrawing(networkId, processor,
+                                                     new IntentData(data, stored.get().installables())));
+            } else {
+                return Optional.of(new VirtualIntentFailed(data));
+            }
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentFailed.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentFailed.java
new file mode 100644
index 0000000..dff1d13
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentFailed.java
@@ -0,0 +1,44 @@
+/*
+ * 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.intent.phase;
+
+import org.onosproject.net.intent.IntentData;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.intent.IntentState.FAILED;
+
+/**
+ * Represents a phase where the compile has failed.
+ */
+public class VirtualIntentFailed extends VirtualFinalIntentProcessPhase {
+
+    private final IntentData data;
+
+    /**
+     * Create an instance with the specified data.
+     *
+     * @param data intentData
+     */
+    VirtualIntentFailed(IntentData data) {
+        this.data = IntentData.nextState(checkNotNull(data), FAILED);
+    }
+
+    @Override
+    public IntentData data() {
+        return data;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentInstallRequest.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentInstallRequest.java
new file mode 100644
index 0000000..08bfec7
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentInstallRequest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.intent.phase;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentProcessor;
+import org.onosproject.net.intent.IntentData;
+
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.incubator.net.virtual.impl.intent.phase.VirtualIntentProcessPhase.transferErrorCount;
+
+/**
+ * Represents a phase where intent installation has been requested
+ * for a virtual network.
+ */
+final class VirtualIntentInstallRequest implements VirtualIntentProcessPhase {
+
+    private final NetworkId networkId;
+    private final VirtualIntentProcessor processor;
+    private final IntentData data;
+    private final Optional<IntentData> stored;
+
+    /**
+     * Creates an install request phase.
+     *
+     * @param networkId virtual network identifier
+     * @param processor  intent processor to be passed to intent process phases
+     *                   generated after this phase
+     * @param intentData intent data to be processed
+     * @param stored     intent data stored in the store
+     */
+    VirtualIntentInstallRequest(NetworkId networkId, VirtualIntentProcessor processor,
+                                IntentData intentData, Optional<IntentData> stored) {
+        this.networkId = checkNotNull(networkId);
+        this.processor = checkNotNull(processor);
+        this.data = checkNotNull(intentData);
+        this.stored = checkNotNull(stored);
+    }
+
+    @Override
+    public Optional<VirtualIntentProcessPhase> execute() {
+        transferErrorCount(data, stored);
+
+        return Optional.of(new VirtualIntentCompiling(networkId, processor, data, stored));
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentInstalling.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentInstalling.java
new file mode 100644
index 0000000..cd8a185
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentInstalling.java
@@ -0,0 +1,66 @@
+/*
+ * 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.intent.phase;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentProcessor;
+import org.onosproject.net.intent.IntentData;
+
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.intent.IntentState.INSTALLING;
+
+/**
+ * Represents a phase where an intent is being installed for a virtual network.
+ */
+//FIXME: better way to implement intent phase and processing for virtual networks?
+public class VirtualIntentInstalling extends VirtualFinalIntentProcessPhase {
+
+    private final NetworkId networkId;
+    private final VirtualIntentProcessor processor;
+    private final IntentData data;
+    private final Optional<IntentData> stored;
+
+    /**
+     * Create an installing phase.
+     *
+     * @param networkId virtual network identifier
+     * @param processor intent processor that does work for installing
+     * @param data      intent data containing an intent to be installed
+     * @param stored    intent data already stored
+     */
+    VirtualIntentInstalling(NetworkId networkId, VirtualIntentProcessor processor,
+                            IntentData data,
+                            Optional<IntentData> stored) {
+        this.networkId = checkNotNull(networkId);
+        this.processor = checkNotNull(processor);
+        this.data = checkNotNull(data);
+        this.stored = checkNotNull(stored);
+        this.data.setState(INSTALLING);
+    }
+
+    @Override
+    public void preExecute() {
+        processor.apply(networkId, stored, Optional.of(data));
+    }
+
+    @Override
+    public IntentData data() {
+        return data;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentProcessPhase.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentProcessPhase.java
new file mode 100644
index 0000000..99fab54
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentProcessPhase.java
@@ -0,0 +1,87 @@
+/*
+ * 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.intent.phase;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentProcessor;
+import org.onosproject.net.intent.IntentData;
+
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Represents a phase of processing an intent.
+ */
+public interface VirtualIntentProcessPhase {
+    /**
+     * Execute the procedure represented by the instance
+     * and generates the next update instance.
+     *
+     * @return next update
+     */
+    Optional<VirtualIntentProcessPhase> execute();
+
+    /**
+     * Create a starting intent process phase according to intent data this class holds.
+     *
+     * @param networkId virtual network identifier
+     * @param processor intent processor to be passed to intent process phases
+     *                  generated while this instance is working
+     * @param data intent data to be processed
+     * @param current intent date that is stored in the store
+     * @return starting intent process phase
+     */
+    static VirtualIntentProcessPhase newInitialPhase(NetworkId networkId,
+                                                     VirtualIntentProcessor processor,
+                                                     IntentData data, IntentData current) {
+        switch (data.request()) {
+            case INSTALL_REQ:
+                return new VirtualIntentInstallRequest(networkId, processor, data,
+                                                       Optional.ofNullable(current));
+            case WITHDRAW_REQ:
+                return new VirtualIntentWithdrawRequest(networkId, processor, data,
+                                                        Optional.ofNullable(current));
+            case PURGE_REQ:
+                return new VirtualIntentPurgeRequest(data, Optional.ofNullable(current));
+            default:
+                // illegal state
+                return new VirtualIntentFailed(data);
+        }
+    }
+
+    static VirtualFinalIntentProcessPhase process(VirtualIntentProcessPhase initial) {
+        Optional<VirtualIntentProcessPhase> currentPhase = Optional.of(initial);
+        VirtualIntentProcessPhase previousPhase = initial;
+
+        while (currentPhase.isPresent()) {
+            previousPhase = currentPhase.get();
+            currentPhase = previousPhase.execute();
+        }
+        return (VirtualFinalIntentProcessPhase) previousPhase;
+    }
+
+    static void transferErrorCount(IntentData data, Optional<IntentData> stored) {
+        stored.ifPresent(storedData -> {
+            if (Objects.equals(data.intent(), storedData.intent()) &&
+                    Objects.equals(data.request(), storedData.request())) {
+                data.setErrorCount(storedData.errorCount());
+            } else {
+                data.setErrorCount(0);
+            }
+        });
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentPurgeRequest.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentPurgeRequest.java
new file mode 100644
index 0000000..a6f29ea
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentPurgeRequest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.intent.phase;
+
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentState;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Represents a phase of requesting a purge of an intent for a virtual network.
+ * Note: The purge will only succeed if the intent is FAILED or WITHDRAWN.
+ */
+final class VirtualIntentPurgeRequest extends VirtualFinalIntentProcessPhase {
+    private static final Logger log = getLogger(VirtualIntentPurgeRequest.class);
+
+    private final IntentData data;
+    protected final Optional<IntentData> stored;
+
+    VirtualIntentPurgeRequest(IntentData intentData, Optional<IntentData> stored) {
+        this.data = checkNotNull(intentData);
+        this.stored = checkNotNull(stored);
+    }
+
+    private boolean shouldAcceptPurge() {
+        if (!stored.isPresent()) {
+            log.info("Purge for intent {}, but intent is not present",
+                     data.key());
+            return true;
+        }
+
+        IntentData storedData = stored.get();
+        if (storedData.state() == IntentState.WITHDRAWN
+                || storedData.state() == IntentState.FAILED) {
+            return true;
+        }
+        log.info("Purge for intent {} is rejected because intent state is {}",
+                 data.key(), storedData.state());
+        return false;
+    }
+
+    @Override
+    public IntentData data() {
+        if (shouldAcceptPurge()) {
+            return data;
+        } else {
+            return stored.get();
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentWithdrawRequest.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentWithdrawRequest.java
new file mode 100644
index 0000000..ce8dfc9
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentWithdrawRequest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.intent.phase;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentProcessor;
+import org.onosproject.net.intent.IntentData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.incubator.net.virtual.impl.intent.phase.VirtualIntentProcessPhase.transferErrorCount;
+
+/**
+ * Represents a phase of requesting a withdraw of an intent for a virtual network.
+ */
+final class VirtualIntentWithdrawRequest implements VirtualIntentProcessPhase {
+    private static final Logger log = LoggerFactory.getLogger(VirtualIntentWithdrawRequest.class);
+
+    private final NetworkId networkId;
+    private final VirtualIntentProcessor processor;
+    private final IntentData data;
+    private final Optional<IntentData> stored;
+
+    /**
+     * Creates a withdraw request phase.
+     *
+     * @param networkId virtual network identifier
+     * @param processor  intent processor to be passed to intent process phases
+     *                   generated after this phase
+     * @param intentData intent data to be processed
+     * @param stored     intent data stored in the store
+     */
+    VirtualIntentWithdrawRequest(NetworkId networkId, VirtualIntentProcessor processor,
+                                 IntentData intentData, Optional<IntentData> stored) {
+        this.networkId = checkNotNull(networkId);
+        this.processor = checkNotNull(processor);
+        this.data = checkNotNull(intentData);
+        this.stored = checkNotNull(stored);
+    }
+
+    @Override
+    public Optional<VirtualIntentProcessPhase> execute() {
+        //TODO perhaps we want to validate that the pending and current are the
+        // same version i.e. they are the same
+        // Note: this call is not just the symmetric version of submit
+
+        transferErrorCount(data, stored);
+
+        if (!stored.isPresent() || stored.get().installables().isEmpty()) {
+            switch (data.request()) {
+                case INSTALL_REQ:
+                    // illegal state?
+                    log.warn("{} was requested to withdraw during installation?", data.intent());
+                    return Optional.of(new VirtualIntentFailed(data));
+                case WITHDRAW_REQ:
+                default: //TODO "default" case should not happen
+                    return Optional.of(new VirtualIntentWithdrawn(data));
+            }
+        }
+
+        return Optional.of(new VirtualIntentWithdrawing(networkId, processor,
+                                                        new IntentData(data, stored.get().installables())));
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentWithdrawing.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentWithdrawing.java
new file mode 100644
index 0000000..f7a2867
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentWithdrawing.java
@@ -0,0 +1,61 @@
+/*
+ * 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.intent.phase;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.impl.intent.VirtualIntentProcessor;
+import org.onosproject.net.intent.IntentData;
+
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.intent.IntentState.WITHDRAWING;
+
+/**
+ * Represents a phase where an intent is withdrawing.
+ */
+final class VirtualIntentWithdrawing extends VirtualFinalIntentProcessPhase {
+
+    private final NetworkId networkId;
+    private final VirtualIntentProcessor processor;
+    private final IntentData data;
+
+    /**
+     * Creates a withdrawing phase.
+     *
+     * @param networkId virtual network identifier
+     * @param processor intent processor that does work for withdrawing
+     * @param data      intent data containing an intent to be withdrawn
+     */
+    VirtualIntentWithdrawing(NetworkId networkId, VirtualIntentProcessor processor,
+                             IntentData data) {
+        this.networkId = checkNotNull(networkId);
+        this.processor = checkNotNull(processor);
+        this.data = checkNotNull(data);
+        this.data.setState(WITHDRAWING);
+    }
+
+    @Override
+    protected void preExecute() {
+        processor.apply(networkId, Optional.of(data), Optional.empty());
+    }
+
+    @Override
+    public IntentData data() {
+        return data;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentWithdrawn.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentWithdrawn.java
new file mode 100644
index 0000000..7e592c2
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/VirtualIntentWithdrawn.java
@@ -0,0 +1,44 @@
+/*
+ * 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.intent.phase;
+
+import org.onosproject.net.intent.IntentData;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.intent.IntentState.WITHDRAWN;
+
+/**
+ * Represents a phase where an intent has been withdrawn for a virtual network.
+ */
+final class VirtualIntentWithdrawn extends VirtualFinalIntentProcessPhase {
+
+    private final IntentData data;
+
+    /**
+     * Create a withdrawn phase.
+     *
+     * @param data intent data containing an intent to be withdrawn
+     */
+    VirtualIntentWithdrawn(IntentData data) {
+        this.data = IntentData.nextState(checkNotNull(data), WITHDRAWN);
+    }
+
+    @Override
+    public IntentData data() {
+        return data;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/package-info.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/package-info.java
new file mode 100644
index 0000000..5fac168
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/intent/phase/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implementations of various intent processing phases for virtual networks.
+ */
+package org.onosproject.incubator.net.virtual.impl.intent.phase;
\ No newline at end of file
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/package-info.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/package-info.java
new file mode 100644
index 0000000..b0750eb
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Implementation of the virtual network subsystem.
+ */
+package org.onosproject.incubator.net.virtual.impl;
\ No newline at end of file
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java
new file mode 100644
index 0000000..436e1d4
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java
@@ -0,0 +1,792 @@
+/*
+ * 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.HashBasedTable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Table;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.InternalRoutingAlgorithm;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.BatchOperationEntry;
+import org.onosproject.net.flow.CompletedBatchOperation;
+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.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleListener;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchEntry;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.topology.TopologyService;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.ImmutableSet.copyOf;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Provider that translate virtual flow rules into physical rules.
+ * Current implementation is based on FlowRules.
+ * This virtualize and de-virtualize virtual flow rules into physical flow rules.
+ * {@link org.onosproject.net.flow.FlowRule}
+ */
+@Component(service = VirtualFlowRuleProvider.class)
+public class DefaultVirtualFlowRuleProvider extends AbstractVirtualProvider
+        implements VirtualFlowRuleProvider {
+
+    private static final String APP_ID_STR = "org.onosproject.virtual.vnet-flow_";
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected TopologyService topologyService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected VirtualNetworkService vnService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected VirtualProviderRegistryService providerRegistryService;
+
+    private InternalRoutingAlgorithm internalRoutingAlgorithm;
+    private InternalVirtualFlowRuleManager frm;
+    private ApplicationId appId;
+    private FlowRuleListener flowRuleListener;
+
+    /**
+     * Creates a provider with the identifier.
+     */
+    public DefaultVirtualFlowRuleProvider() {
+        super(new ProviderId("vnet-flow", "org.onosproject.virtual.vnet-flow"));
+    }
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(APP_ID_STR);
+
+        providerRegistryService.registerProvider(this);
+
+        flowRuleListener = new InternalFlowRuleListener();
+        flowRuleService.addListener(flowRuleListener);
+
+        internalRoutingAlgorithm = new DefaultInternalRoutingAlgorithm();
+        frm = new InternalVirtualFlowRuleManager();
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        flowRuleService.removeListener(flowRuleListener);
+        flowRuleService.removeFlowRulesById(appId);
+        providerRegistryService.unregisterProvider(this);
+        log.info("Stopped");
+    }
+
+    @Modified
+    protected void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+    }
+
+    @Override
+    public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
+        for (FlowRule flowRule : flowRules) {
+            devirtualize(networkId, flowRule).forEach(
+                    r -> flowRuleService.applyFlowRules(r));
+        }
+    }
+
+    @Override
+    public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
+        for (FlowRule flowRule : flowRules) {
+            devirtualize(networkId, flowRule).forEach(
+                    r -> flowRuleService.removeFlowRules(r));
+        }
+    }
+
+    @Override
+    public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
+        checkNotNull(batch);
+
+        for (FlowRuleBatchEntry fop : batch.getOperations()) {
+            FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+
+            switch (fop.operator()) {
+                case ADD:
+                    devirtualize(networkId, fop.target()).forEach(builder::add);
+                    break;
+                case REMOVE:
+                    devirtualize(networkId, fop.target()).forEach(builder::remove);
+                    break;
+                case MODIFY:
+                    devirtualize(networkId, fop.target()).forEach(builder::modify);
+                    break;
+                default:
+                    break;
+            }
+
+            flowRuleService.apply(builder.build(new FlowRuleOperationsContext() {
+                @Override
+                public void onSuccess(FlowRuleOperations ops) {
+                    CompletedBatchOperation status =
+                            new CompletedBatchOperation(true,
+                                                        Sets.newConcurrentHashSet(),
+                                                        batch.deviceId());
+
+                    VirtualFlowRuleProviderService providerService =
+                            (VirtualFlowRuleProviderService) providerRegistryService
+                                    .getProviderService(networkId,
+                                                        VirtualFlowRuleProvider.class);
+                    providerService.batchOperationCompleted(batch.id(), status);
+                }
+
+                @Override
+                public void onError(FlowRuleOperations ops) {
+                    Set<FlowRule> failures = ImmutableSet.copyOf(
+                            Lists.transform(batch.getOperations(),
+                                            BatchOperationEntry::target));
+
+                    CompletedBatchOperation status =
+                            new CompletedBatchOperation(false,
+                                                        failures,
+                                                        batch.deviceId());
+
+                    VirtualFlowRuleProviderService providerService =
+                            (VirtualFlowRuleProviderService) providerRegistryService
+                                    .getProviderService(networkId,
+                                                        VirtualFlowRuleProvider.class);
+                    providerService.batchOperationCompleted(batch.id(), status);
+                }
+            }));
+        }
+    }
+
+    public void setEmbeddingAlgorithm(InternalRoutingAlgorithm
+                                              internalRoutingAlgorithm) {
+        this.internalRoutingAlgorithm = internalRoutingAlgorithm;
+    }
+
+    /**
+     * Translate the requested physical flow rules into virtual flow rules.
+     *
+     * @param flowRule A virtual flow rule to be translated
+     * @return A flow rule for a specific virtual network
+     */
+    private FlowRule virtualizeFlowRule(FlowRule flowRule) {
+
+        FlowRule storedrule = frm.getVirtualRule(flowRule);
+
+        if (flowRule.reason() == FlowRule.FlowRemoveReason.NO_REASON) {
+            return storedrule;
+        } else {
+            return DefaultFlowRule.builder()
+                    .withReason(flowRule.reason())
+                    .withPriority(storedrule.priority())
+                    .forDevice(storedrule.deviceId())
+                    .forTable(storedrule.tableId())
+                    .fromApp(new DefaultApplicationId(storedrule.appId(), null))
+                    .withIdleTimeout(storedrule.timeout())
+                    .withHardTimeout(storedrule.hardTimeout())
+                    .withSelector(storedrule.selector())
+                    .withTreatment(storedrule.treatment())
+                    .build();
+        }
+    }
+
+    private FlowEntry virtualize(FlowEntry flowEntry) {
+        FlowRule vRule = virtualizeFlowRule(flowEntry);
+
+        if (vRule == null) {
+            return null;
+        }
+
+        FlowEntry vEntry = new DefaultFlowEntry(vRule, flowEntry.state(),
+                                                flowEntry.life(),
+                                                flowEntry.packets(),
+                                                flowEntry.bytes());
+        return vEntry;
+    }
+
+    /**
+     * Translate the requested virtual flow rules into physical flow rules.
+     * The translation could be one to many.
+     *
+     * @param flowRule A flow rule from underlying data plane to be translated
+     * @return A set of flow rules for physical network
+     */
+    private Set<FlowRule> devirtualize(NetworkId networkId, FlowRule flowRule) {
+
+        Set<FlowRule> outRules = new HashSet<>();
+
+        Set<ConnectPoint> ingressPoints = extractIngressPoints(networkId,
+                                                               flowRule.deviceId(),
+                                                               flowRule.selector());
+
+        ConnectPoint egressPoint = extractEgressPoints(networkId,
+                                                         flowRule.deviceId(),
+                                                         flowRule.treatment());
+
+        if (egressPoint == null) {
+            return outRules;
+        }
+
+        TrafficSelector.Builder commonSelectorBuilder
+                = DefaultTrafficSelector.builder();
+        flowRule.selector().criteria().stream()
+                .filter(c -> c.type() != Criterion.Type.IN_PORT)
+                .forEach(c -> commonSelectorBuilder.add(c));
+        TrafficSelector commonSelector = commonSelectorBuilder.build();
+
+        TrafficTreatment.Builder commonTreatmentBuilder
+                = DefaultTrafficTreatment.builder();
+        flowRule.treatment().allInstructions().stream()
+                .filter(i -> i.type() != Instruction.Type.OUTPUT)
+                .forEach(i -> commonTreatmentBuilder.add(i));
+        TrafficTreatment commonTreatment = commonTreatmentBuilder.build();
+
+        for (ConnectPoint ingressPoint : ingressPoints) {
+            if (egressPoint.port() == PortNumber.FLOOD) {
+                Set<ConnectPoint> outPoints = vnService
+                        .getVirtualPorts(networkId, flowRule.deviceId())
+                        .stream()
+                        .map(VirtualPort::realizedBy)
+                        .filter(p -> !p.equals(ingressPoint))
+                        .collect(Collectors.toSet());
+
+                for (ConnectPoint outPoint : outPoints) {
+                    outRules.addAll(generateRules(networkId, ingressPoint, outPoint,
+                                                  commonSelector, commonTreatment, flowRule));
+                }
+            } else {
+                outRules.addAll(generateRules(networkId, ingressPoint, egressPoint,
+                                              commonSelector, commonTreatment, flowRule));
+            }
+        }
+
+        return outRules;
+    }
+
+    /**
+     * Extract ingress connect points of the physical network
+     * from the requested traffic selector.
+     *
+     * @param networkId the virtual network identifier
+     * @param deviceId the virtual device identifier
+     * @param selector the traffic selector to extract ingress point
+     * @return the set of ingress connect points of the physical network
+     */
+    private Set<ConnectPoint> extractIngressPoints(NetworkId networkId,
+                                                   DeviceId deviceId,
+                                                   TrafficSelector selector) {
+
+        Set<ConnectPoint> ingressPoints = new HashSet<>();
+
+        Set<VirtualPort> vPorts = vnService
+                .getVirtualPorts(networkId, deviceId);
+
+        PortCriterion portCriterion = ((PortCriterion) selector
+                .getCriterion(Criterion.Type.IN_PORT));
+
+        if (portCriterion != null) {
+            PortNumber vInPortNum = portCriterion.port();
+
+            Optional<ConnectPoint> optionalCp =  vPorts.stream()
+                    .filter(v -> v.number().equals(vInPortNum))
+                    .map(VirtualPort::realizedBy).findFirst();
+            if (!optionalCp.isPresent()) {
+                log.warn("Port {} is not realized yet, in Network {}, Device {}",
+                         vInPortNum, networkId, deviceId);
+                return ingressPoints;
+            }
+
+            ingressPoints.add(optionalCp.get());
+        } else {
+            for (VirtualPort vPort : vPorts) {
+                if (vPort.realizedBy() != null) {
+                    ingressPoints.add(vPort.realizedBy());
+                } else {
+                    log.warn("Port {} is not realized yet, in Network {}, " +
+                                     "Device {}",
+                             vPort, networkId, deviceId);
+                }
+            }
+        }
+
+        return ingressPoints;
+    }
+
+    /**
+     * Extract egress connect point of the physical network
+     * from the requested traffic treatment.
+     *
+     * @param networkId the virtual network identifier
+     * @param deviceId the virtual device identifier
+     * @param treatment the traffic treatment to extract ingress point
+     * @return the egress connect point of the physical network
+     */
+    private ConnectPoint extractEgressPoints(NetworkId networkId,
+                                                  DeviceId deviceId,
+                                                  TrafficTreatment treatment) {
+
+        Set<VirtualPort> vPorts = vnService
+                .getVirtualPorts(networkId, deviceId);
+
+        PortNumber vOutPortNum = treatment.allInstructions().stream()
+                .filter(i -> i.type() == Instruction.Type.OUTPUT)
+                .map(i -> ((Instructions.OutputInstruction) i).port())
+                .findFirst().get();
+
+        Optional<ConnectPoint> optionalCpOut = vPorts.stream()
+                .filter(v -> v.number().equals(vOutPortNum))
+                .map(VirtualPort::realizedBy)
+                .findFirst();
+
+        if (!optionalCpOut.isPresent()) {
+            if (vOutPortNum.isLogical()) {
+                return new ConnectPoint(DeviceId.deviceId("vNet"), vOutPortNum);
+            }
+
+            log.warn("Port {} is not realized yet, in Network {}, Device {}",
+                     vOutPortNum, networkId, deviceId);
+            return null;
+        }
+
+        return optionalCpOut.get();
+    }
+
+
+    /**
+     * Generates the corresponding flow rules for the physical network.
+     *
+     * @param networkId The virtual network identifier
+     * @param ingressPoint The ingress point of the physical network
+     * @param egressPoint The egress point of the physical network
+     * @param commonSelector A common traffic selector between the virtual
+     *                       and physical flow rules
+     * @param commonTreatment A common traffic treatment between the virtual
+     *                        and physical flow rules
+     * @param flowRule The virtual flow rule to be translated
+     * @return A set of flow rules for the physical network
+     */
+    private Set<FlowRule> generateRules(NetworkId networkId,
+                                        ConnectPoint ingressPoint,
+                                        ConnectPoint egressPoint,
+                                        TrafficSelector commonSelector,
+                                        TrafficTreatment commonTreatment,
+                                        FlowRule flowRule) {
+
+        if (ingressPoint.deviceId().equals(egressPoint.deviceId()) ||
+                egressPoint.port().isLogical()) {
+            return generateRuleForSingle(networkId, ingressPoint, egressPoint,
+                                         commonSelector, commonTreatment, flowRule);
+        } else {
+            return generateRuleForMulti(networkId, ingressPoint, egressPoint,
+                                         commonSelector, commonTreatment, flowRule);
+        }
+    }
+
+    /**
+     * Generate physical rules when a virtual flow rule can be handled inside
+     * a single physical switch.
+     *
+     * @param networkId The virtual network identifier
+     * @param ingressPoint The ingress point of the physical network
+     * @param egressPoint The egress point of the physical network
+     * @param commonSelector A common traffic selector between the virtual
+     *                       and physical flow rules
+     * @param commonTreatment A common traffic treatment between the virtual
+     *                        and physical flow rules
+     * @param flowRule The virtual flow rule to be translated
+     * @return A set of flow rules for the physical network
+     */
+    private Set<FlowRule> generateRuleForSingle(NetworkId networkId,
+            ConnectPoint ingressPoint,
+            ConnectPoint egressPoint,
+            TrafficSelector commonSelector,
+            TrafficTreatment commonTreatment,
+            FlowRule flowRule) {
+
+        Set<FlowRule> outRules = new HashSet<>();
+
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector
+                .builder(commonSelector)
+                .matchInPort(ingressPoint.port());
+
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment
+                .builder(commonTreatment)
+                .setOutput(egressPoint.port());
+
+        FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+                .fromApp(vnService.getVirtualNetworkApplicationId(networkId))
+                .forDevice(ingressPoint.deviceId())
+                .withSelector(selectorBuilder.build())
+                .withTreatment(treatmentBuilder.build())
+                .withIdleTimeout(flowRule.timeout())
+                .withPriority(flowRule.priority());
+
+        FlowRule rule = ruleBuilder.build();
+        frm.addIngressRule(flowRule, rule, networkId);
+        outRules.add(rule);
+
+        return outRules;
+    }
+
+    /**
+     * Generate physical rules when a virtual flow rule can be handled with
+     * multiple physical switches.
+     *
+     * @param networkId The virtual network identifier
+     * @param ingressPoint The ingress point of the physical network
+     * @param egressPoint The egress point of the physical network
+     * @param commonSelector A common traffic selector between the virtual
+     *                       and physical flow rules
+     * @param commonTreatment A common traffic treatment between the virtual
+     *                        and physical flow rules
+     * @param flowRule The virtual flow rule to be translated
+     * @return A set of flow rules for the physical network
+     */
+    private Set<FlowRule> generateRuleForMulti(NetworkId networkId,
+                                                ConnectPoint ingressPoint,
+                                                ConnectPoint egressPoint,
+                                                TrafficSelector commonSelector,
+                                                TrafficTreatment commonTreatment,
+                                                FlowRule flowRule) {
+        Set<FlowRule> outRules = new HashSet<>();
+
+        Path internalPath = internalRoutingAlgorithm
+                .findPath(ingressPoint, egressPoint);
+        checkNotNull(internalPath, "No path between " +
+                ingressPoint.toString() + " " + egressPoint.toString());
+
+        ConnectPoint outCp = internalPath.links().get(0).src();
+
+        //ingress point of tunnel
+        TrafficSelector.Builder selectorBuilder =
+                DefaultTrafficSelector.builder(commonSelector);
+        selectorBuilder.matchInPort(ingressPoint.port());
+
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder(commonTreatment);
+        //TODO: add the logic to check host location
+        treatmentBuilder.pushVlan()
+                .setVlanId(VlanId.vlanId(networkId.id().shortValue()));
+        treatmentBuilder.setOutput(outCp.port());
+
+        FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+                .fromApp(vnService.getVirtualNetworkApplicationId(networkId))
+                .forDevice(ingressPoint.deviceId())
+                .withSelector(selectorBuilder.build())
+                .withIdleTimeout(flowRule.timeout())
+                .withTreatment(treatmentBuilder.build())
+                .withPriority(flowRule.priority());
+
+        FlowRule rule = ruleBuilder.build();
+        frm.addIngressRule(flowRule, rule, networkId);
+        outRules.add(rule);
+
+        //routing inside tunnel
+        ConnectPoint inCp = internalPath.links().get(0).dst();
+
+        if (internalPath.links().size() > 1) {
+            for (Link l : internalPath.links()
+                    .subList(1, internalPath.links().size())) {
+
+                outCp = l.src();
+
+                selectorBuilder = DefaultTrafficSelector
+                        .builder(commonSelector)
+                        .matchVlanId(VlanId.vlanId(networkId.id().shortValue()))
+                        .matchInPort(inCp.port());
+
+                treatmentBuilder = DefaultTrafficTreatment
+                        .builder(commonTreatment)
+                        .setOutput(outCp.port());
+
+                ruleBuilder = DefaultFlowRule.builder()
+                        .fromApp(vnService.getVirtualNetworkApplicationId(networkId))
+                        .forDevice(inCp.deviceId())
+                        .withSelector(selectorBuilder.build())
+                        .withTreatment(treatmentBuilder.build())
+                        .withIdleTimeout(flowRule.timeout())
+                        .withPriority(flowRule.priority());
+
+                outRules.add(ruleBuilder.build());
+                inCp = l.dst();
+            }
+        }
+
+        //egress point of tunnel
+        selectorBuilder = DefaultTrafficSelector.builder(commonSelector)
+                .matchVlanId(VlanId.vlanId(networkId.id().shortValue()))
+                .matchInPort(inCp.port());
+
+        treatmentBuilder = DefaultTrafficTreatment.builder(commonTreatment)
+                .popVlan()
+                .setOutput(egressPoint.port());
+
+        ruleBuilder = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .forDevice(egressPoint.deviceId())
+                .withSelector(selectorBuilder.build())
+                .withTreatment(treatmentBuilder.build())
+                .withIdleTimeout(flowRule.timeout())
+                .withPriority(flowRule.priority());
+
+        outRules.add(ruleBuilder.build());
+
+        return outRules;
+    }
+
+    private class InternalFlowRuleListener implements FlowRuleListener {
+        @Override
+        public void event(FlowRuleEvent event) {
+            if ((event.type() == FlowRuleEvent.Type.RULE_ADDED) ||
+                    (event.type() == FlowRuleEvent.Type.RULE_UPDATED)) {
+                if (frm.isVirtualIngressRule(event.subject())) {
+                    NetworkId networkId = frm.getVirtualNetworkId(event.subject());
+                    FlowEntry vEntry = getVirtualFlowEntry(event.subject());
+
+                    if (vEntry == null) {
+                        return;
+                    }
+
+                    frm.addOrUpdateFlowEntry(networkId, vEntry.deviceId(), vEntry);
+
+                    VirtualFlowRuleProviderService providerService =
+                            (VirtualFlowRuleProviderService) providerRegistryService
+                                    .getProviderService(networkId,
+                                                        VirtualFlowRuleProvider.class);
+
+                    ImmutableList.Builder<FlowEntry> builder = ImmutableList.builder();
+                    builder.addAll(frm.getFlowEntries(networkId, vEntry.deviceId()));
+
+                    providerService.pushFlowMetrics(vEntry.deviceId(), builder.build());
+                }
+            } else if (event.type() == FlowRuleEvent.Type.RULE_REMOVED) {
+                if (frm.isVirtualIngressRule(event.subject())) {
+                    //FIXME confirm all physical rules are removed
+                    NetworkId networkId = frm.getVirtualNetworkId(event.subject());
+                    FlowEntry vEntry = getVirtualFlowEntry(event.subject());
+
+                    if (vEntry == null) {
+                        return;
+                    }
+
+                    frm.removeFlowEntry(networkId, vEntry.deviceId(), vEntry);
+                    frm.removeFlowRule(networkId, vEntry.deviceId(), vEntry);
+
+                    VirtualFlowRuleProviderService providerService =
+                            (VirtualFlowRuleProviderService) providerRegistryService
+                                    .getProviderService(networkId,
+                                                        VirtualFlowRuleProvider.class);
+                    providerService.flowRemoved(vEntry);
+                }
+            }
+        }
+
+        private FlowEntry getVirtualFlowEntry(FlowRule rule) {
+            FlowEntry entry = null;
+            for (FlowEntry fe :
+                    flowRuleService.getFlowEntries(rule.deviceId())) {
+                if (rule.exactMatch(fe)) {
+                    entry = fe;
+                }
+            }
+
+            if (entry != null) {
+                return virtualize(entry);
+            } else  {
+                return virtualize(new DefaultFlowEntry(rule,
+                                                       FlowEntry.FlowEntryState.PENDING_REMOVE));
+            }
+        }
+    }
+
+    private class InternalVirtualFlowRuleManager {
+        /** <Virtual Network ID, Virtual Device ID, Virtual Flow Rules>.*/
+        final Table<NetworkId, DeviceId, Set<FlowRule>> flowRuleTable
+                = HashBasedTable.create();
+
+        /** <Virtual Network ID, Virtual Device ID, Virtual Flow Entries>.*/
+        final Table<NetworkId, DeviceId, Set<FlowEntry>> flowEntryTable
+                = HashBasedTable.create();
+
+        /** <Physical Flow Rule, Virtual Network ID>.*/
+        final Map<FlowRule, NetworkId> ingressRuleMap = Maps.newHashMap();
+
+        /** <Physical Flow Rule, Virtual Virtual Flow Rule>.*/
+        final Map<FlowRule, FlowRule> virtualizationMap = Maps.newHashMap();
+
+        private Iterable<FlowRule> getFlowRules(NetworkId networkId,
+                                                DeviceId deviceId) {
+            return flowRuleTable.get(networkId, deviceId);
+        }
+
+        private Iterable<FlowEntry> getFlowEntries(NetworkId networkId,
+                                                   DeviceId deviceId) {
+            return flowEntryTable.get(networkId, deviceId);
+        }
+
+        private void addFlowRule(NetworkId networkId, DeviceId deviceId,
+                                 FlowRule flowRule) {
+            Set<FlowRule> set = flowRuleTable.get(networkId, deviceId);
+            if (set == null) {
+                set = Sets.newHashSet();
+                flowRuleTable.put(networkId, deviceId, set);
+            }
+            set.add(flowRule);
+        }
+
+        private void removeFlowRule(NetworkId networkId, DeviceId deviceId,
+                                    FlowRule flowRule) {
+            Set<FlowRule> set = flowRuleTable.get(networkId, deviceId);
+            if (set == null) {
+                return;
+            }
+            set.remove(flowRule);
+        }
+
+        private void addOrUpdateFlowEntry(NetworkId networkId, DeviceId deviceId,
+                                  FlowEntry flowEntry) {
+            Set<FlowEntry> set = flowEntryTable.get(networkId, deviceId);
+            if (set == null) {
+                set = Sets.newConcurrentHashSet();
+                flowEntryTable.put(networkId, deviceId, set);
+            }
+
+            //Replace old entry with new one
+            set.stream().filter(fe -> fe.exactMatch(flowEntry))
+                    .forEach(set::remove);
+            set.add(flowEntry);
+        }
+
+        private void removeFlowEntry(NetworkId networkId, DeviceId deviceId,
+                                     FlowEntry flowEntry) {
+            Set<FlowEntry> set = flowEntryTable.get(networkId, deviceId);
+            if (set == null) {
+                return;
+            }
+            set.remove(flowEntry);
+        }
+
+        private void addIngressRule(FlowRule virtualRule, FlowRule physicalRule,
+                                    NetworkId networkId) {
+            ingressRuleMap.put(physicalRule, networkId);
+            virtualizationMap.put(physicalRule, virtualRule);
+        }
+
+        private FlowRule getVirtualRule(FlowRule physicalRule) {
+                return virtualizationMap.get(physicalRule);
+        }
+
+        private void removeIngressRule(FlowRule physicalRule) {
+            ingressRuleMap.remove(physicalRule);
+            virtualizationMap.remove(physicalRule);
+        }
+
+        private Set<FlowRule> getAllPhysicalRule() {
+            return copyOf(virtualizationMap.keySet());
+        }
+
+        private NetworkId getVirtualNetworkId(FlowRule physicalRule) {
+            return ingressRuleMap.get(physicalRule);
+        }
+
+        /**
+         * Test the rule is the ingress rule for virtual rules.
+         *
+         * @param flowRule A flow rule from underlying data plane to be translated
+         * @return True when the rule is for ingress point for a virtual switch
+         */
+        private boolean isVirtualIngressRule(FlowRule flowRule) {
+            return ingressRuleMap.containsKey(flowRule);
+        }
+    }
+
+    private class DefaultInternalRoutingAlgorithm
+            implements InternalRoutingAlgorithm {
+
+        @Override
+        public Path findPath(ConnectPoint src, ConnectPoint dst) {
+            Set<Path> paths =
+                    topologyService.getPaths(topologyService.currentTopology(),
+                                             src.deviceId(),
+                                             dst.deviceId());
+
+            if (paths.isEmpty()) {
+                return null;
+            }
+
+            //TODO the logic find the best path
+            return (Path) paths.toArray()[0];
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualGroupProvider.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualGroupProvider.java
new file mode 100644
index 0000000..7cc86cc
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualGroupProvider.java
@@ -0,0 +1,128 @@
+/*
+ * 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.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualGroupProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.group.GroupEvent;
+import org.onosproject.net.group.GroupListener;
+import org.onosproject.net.group.GroupOperation;
+import org.onosproject.net.group.GroupOperations;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.provider.ProviderId;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Provider to handle Group for virtual network.
+ */
+@Component(service = VirtualGroupProvider.class)
+public class DefaultVirtualGroupProvider extends AbstractVirtualProvider
+        implements VirtualGroupProvider {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected VirtualProviderRegistryService providerRegistryService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected GroupService groupService;
+
+    private InternalGroupEventListener internalGroupEventListener;
+
+    /**
+     * Creates a virtual provider with the supplied identifier.
+     */
+    public DefaultVirtualGroupProvider() {
+        super(new ProviderId("vnet-group", "org.onosproject.virtual.of-group"));
+    }
+
+    @Activate
+    public void activate() {
+        providerRegistryService.registerProvider(this);
+
+        internalGroupEventListener = new InternalGroupEventListener();
+        groupService.addListener(internalGroupEventListener);
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        groupService.removeListener(internalGroupEventListener);
+        providerRegistryService.unregisterProvider(this);
+    }
+
+    @Modified
+    protected void modified(ComponentContext context) {
+    }
+
+    @Override
+    public void performGroupOperation(NetworkId networkId, DeviceId deviceId, GroupOperations groupOps) {
+        for (GroupOperation groupOperation: groupOps.operations()) {
+            switch (groupOperation.opType()) {
+                case ADD:
+                    //TODO: devirtualize + groupAdd
+                    log.info("Group Add is not supported, yet");
+                    break;
+                case MODIFY:
+                    //TODO: devirtualize + groupMod
+                    log.info("Group Modify is not supported, yet");
+                    break;
+                case DELETE:
+                    //TODO: devirtualize + groupDel
+                    log.info("Group Delete is not supported, yet");
+                    break;
+                default:
+                    log.error("Unsupported Group operation");
+                    return;
+            }
+        }
+    }
+
+    private class InternalGroupEventListener implements GroupListener {
+        @Override
+        public void event(GroupEvent event) {
+            switch (event.type()) {
+                //TODO: virtualize + notify to virtual provider service
+                case GROUP_ADD_REQUESTED:
+                case GROUP_UPDATE_REQUESTED:
+                case GROUP_REMOVE_REQUESTED:
+                case GROUP_ADDED:
+                case GROUP_UPDATED:
+                case GROUP_REMOVED:
+                case GROUP_ADD_FAILED:
+                case GROUP_UPDATE_FAILED:
+                case GROUP_REMOVE_FAILED:
+                case GROUP_BUCKET_FAILOVER:
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualMeterProvider.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualMeterProvider.java
new file mode 100644
index 0000000..26462ad
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualMeterProvider.java
@@ -0,0 +1,264 @@
+/*
+ * 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 com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.RemovalCause;
+import com.google.common.cache.RemovalNotification;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualMeterProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualMeterProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterEvent;
+import org.onosproject.net.meter.MeterFailReason;
+import org.onosproject.net.meter.MeterListener;
+import org.onosproject.net.meter.MeterOperation;
+import org.onosproject.net.meter.MeterOperations;
+import org.onosproject.net.meter.MeterService;
+import org.onosproject.net.provider.ProviderId;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Provider to handle meters for virtual networks.
+ */
+@Component(service = VirtualMeterProvider.class)
+public class DefaultVirtualMeterProvider extends AbstractVirtualProvider
+        implements VirtualMeterProvider {
+
+    private final Logger log = getLogger(getClass());
+
+    static final long TIMEOUT = 30;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected VirtualProviderRegistryService providerRegistryService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected MeterService meterService;
+
+    private MeterListener internalMeterListener;
+    private Cache<Long, VirtualMeterOperation> pendingOperations;
+    private IdGenerator idGenerator;
+
+    @Activate
+    public void activate() {
+        providerRegistryService.registerProvider(this);
+        internalMeterListener = new InternalMeterListener();
+
+        idGenerator = getIdGenerator();
+
+        pendingOperations = CacheBuilder.newBuilder()
+                .expireAfterWrite(TIMEOUT, TimeUnit.SECONDS)
+                .removalListener(
+                        (RemovalNotification<Long, VirtualMeterOperation>
+                                 notification) -> {
+                    if (notification.getCause() == RemovalCause.EXPIRED) {
+                        NetworkId networkId = notification.getValue().networkId();
+                        MeterOperation op = notification.getValue().operation();
+
+                        VirtualMeterProviderService providerService =
+                                (VirtualMeterProviderService) providerRegistryService
+                                        .getProviderService(networkId,
+                                                            VirtualMeterProvider.class);
+
+                        providerService.meterOperationFailed(op,
+                                                             MeterFailReason.TIMEOUT);
+                    }
+                }).build();
+
+        meterService.addListener(internalMeterListener);
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        meterService.removeListener(internalMeterListener);
+        providerRegistryService.unregisterProvider(this);
+    }
+
+    /**
+     * Creates a provider with the identifier.
+     */
+    public DefaultVirtualMeterProvider() {
+        super(new ProviderId("vnet-meter",
+                             "org.onosproject.virtual.vnet-meter"));
+    }
+
+    @Override
+    public void performMeterOperation(NetworkId networkId, DeviceId deviceId,
+                                      MeterOperations meterOps) {
+        meterOps.operations().forEach(op -> performOperation(networkId, deviceId, op));
+    }
+
+    @Override
+    public void performMeterOperation(NetworkId networkId, DeviceId deviceId,
+                                      MeterOperation meterOp) {
+        performOperation(networkId, deviceId, meterOp);
+    }
+
+    private void performOperation(NetworkId networkId, DeviceId deviceId,
+                                  MeterOperation op) {
+
+        VirtualMeterOperation vOp = new VirtualMeterOperation(networkId, op);
+        pendingOperations.put(idGenerator.getNewId(), vOp);
+
+        switch (op.type()) {
+            case ADD:
+                //TODO: devirtualize + submit
+                break;
+            case REMOVE:
+                //TODO: devirtualize + withdraw
+                break;
+            case MODIFY:
+                //TODO: devitualize + withdraw and submit
+                break;
+            default:
+                log.warn("Unknown Meter command {}; not sending anything",
+                         op.type());
+                VirtualMeterProviderService providerService =
+                        (VirtualMeterProviderService) providerRegistryService
+                                .getProviderService(networkId,
+                                                    VirtualMeterProvider.class);
+                providerService.meterOperationFailed(op,
+                                                     MeterFailReason.UNKNOWN_COMMAND);
+        }
+
+    }
+
+    /**
+     * De-virtualizes a meter operation.
+     * It takes a virtual meter operation, and translate it to a physical meter operation.
+     *
+     * @param networkId a virtual network identifier
+     * @param deviceId a virtual network device identifier
+     * @param meterOps a meter operation to be de-virtualized
+     * @return de-virtualized meter operation
+     */
+    private VirtualMeterOperation devirtualize(NetworkId networkId,
+                                      DeviceId deviceId,
+                                      MeterOperation meterOps) {
+        return null;
+    }
+
+    /**
+     * Virtualizes meter.
+     * This translates meter events for virtual networks before delivering them.
+     *
+     * @param meter
+     * @return
+     */
+    private Meter virtualize(Meter meter) {
+        return  null;
+    }
+
+
+    private class InternalMeterListener implements MeterListener {
+        @Override
+        public void event(MeterEvent event) {
+            //TODO: virtualize + notify event to meter provider service
+            //Is it enough to enable virtual network provider?
+            switch (event.type()) {
+                case METER_ADD_REQ:
+                    break;
+                case METER_REM_REQ:
+                    break;
+                case METER_ADDED:
+                    break;
+                case METER_REMOVED:
+                    break;
+                default:
+                    log.warn("Unknown meter event {}", event.type());
+            }
+        }
+    }
+
+    /**
+     * A class to hold a network identifier and a meter operation.
+     * This class is designed to be used only in virtual network meter provider.
+     */
+    private final class VirtualMeterOperation {
+        private NetworkId networkId;
+        private MeterOperation op;
+
+        private VirtualMeterOperation(NetworkId networkId, MeterOperation op) {
+            this.networkId = networkId;
+            this.op = op;
+        }
+
+        private NetworkId networkId() {
+            return networkId;
+        }
+
+        private MeterOperation operation() {
+            return this.op;
+        }
+    }
+
+    /**
+     * A class to hold a network identifier and a meter.
+     * This class is designed to be used in only virtual network meter provider.
+     */
+    private final class VirtualMeter {
+        private NetworkId networkId;
+        private Meter meter;
+
+        private VirtualMeter(NetworkId networkId, Meter meter) {
+            this.networkId = networkId;
+            this.meter = meter;
+        }
+
+        private NetworkId networkId() {
+            return this.networkId;
+        }
+
+        private Meter meter() {
+            return this.meter;
+        }
+    }
+
+    /**
+     * Id generator for virtual meters to guarantee the uniqueness of its identifier
+     * among multiple virtual network meters.
+     *
+     * @return an ID generator
+     */
+    private IdGenerator getIdGenerator() {
+        return new IdGenerator() {
+            private AtomicLong counter = new AtomicLong(0);
+
+            @Override
+            public long getNewId() {
+                return counter.getAndIncrement();
+            }
+        };
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualNetworkProvider.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualNetworkProvider.java
new file mode 100644
index 0000000..3860dee
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualNetworkProvider.java
@@ -0,0 +1,163 @@
+/*
+ * 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.onosproject.incubator.net.virtual.DefaultVirtualLink;
+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.net.ConnectPoint;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyCluster;
+import org.onosproject.net.topology.TopologyEvent;
+import org.onosproject.net.topology.TopologyListener;
+import org.onosproject.net.topology.TopologyService;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Virtual network topology provider.
+ */
+@Component(service = VirtualNetworkProvider.class)
+public class DefaultVirtualNetworkProvider
+        extends AbstractProvider implements VirtualNetworkProvider {
+
+    private final Logger log = getLogger(DefaultVirtualNetworkProvider.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected VirtualNetworkProviderRegistry providerRegistry;
+
+    private VirtualNetworkProviderService providerService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected TopologyService topologyService;
+
+    protected TopologyListener topologyListener = new InternalTopologyListener();
+
+    private ExecutorService executor;
+
+    /**
+     * Default constructor.
+     */
+    public DefaultVirtualNetworkProvider() {
+        super(DefaultVirtualLink.PID);
+    }
+
+    @Activate
+    public void activate() {
+        executor = newSingleThreadExecutor(groupedThreads("onos/vnet", "provider", log));
+        providerService = providerRegistry.register(this);
+        topologyService.addListener(topologyListener);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        topologyService.removeListener(topologyListener);
+        executor.shutdownNow();
+        executor = null;
+        providerRegistry.unregister(this);
+        providerService = null;
+        log.info("Stopped");
+    }
+
+    @Override
+    public boolean isTraversable(ConnectPoint src, ConnectPoint dst) {
+        final boolean[] foundSrc = new boolean[1];
+        final boolean[] foundDst = new boolean[1];
+        Topology topology = topologyService.currentTopology();
+        Set<Path> paths = topologyService.getPaths(topology, src.deviceId(), dst.deviceId());
+        paths.forEach(path -> {
+            foundDst[0] = false;
+            foundSrc[0] = false;
+            // Traverse the links in each path to determine if both the src and dst connection
+            // point are in the path, if so then this src/dst pair are traversable.
+            path.links().forEach(link -> {
+                if (link.src().equals(src)) {
+                    foundSrc[0] = true;
+                }
+                if (link.dst().equals(dst)) {
+                    foundDst[0] = true;
+                }
+            });
+            if (foundSrc[0] && foundDst[0]) {
+                return;
+            }
+        });
+        return foundSrc[0] && foundDst[0];
+    }
+
+    /**
+     * Returns a set of set of interconnected connect points in the default topology.
+     * The inner set represents the interconnected connect points, and the outerset
+     * represents separate clusters.
+     *
+     * @param topology the default topology
+     * @return set of set of interconnected connect points.
+     */
+    public Set<Set<ConnectPoint>> getConnectPoints(Topology topology) {
+        Set<Set<ConnectPoint>> clusters = new HashSet<>();
+        Set<TopologyCluster> topologyClusters = topologyService.getClusters(topology);
+        topologyClusters.forEach(topologyCluster -> {
+            Set<ConnectPoint> connectPointSet = new HashSet<>();
+            Set<Link> clusterLinks =
+                    topologyService.getClusterLinks(topology, topologyCluster);
+            clusterLinks.forEach(link -> {
+                connectPointSet.add(link.src());
+                connectPointSet.add(link.dst());
+            });
+            if (!connectPointSet.isEmpty()) {
+                clusters.add(connectPointSet);
+            }
+        });
+        return clusters;
+    }
+
+    /**
+     * Topology event listener.
+     */
+    private class InternalTopologyListener implements TopologyListener {
+        @Override
+        public void event(TopologyEvent event) {
+            // Perform processing off the listener thread.
+            executor.submit(() -> providerService
+                    .topologyChanged(getConnectPoints(event.subject())));
+        }
+
+        @Override
+        public boolean isRelevant(TopologyEvent event) {
+            return event.type() == TopologyEvent.Type.TOPOLOGY_CHANGED &&
+                    event.reasons().stream().anyMatch(reason -> reason instanceof LinkEvent);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketContext.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketContext.java
new file mode 100644
index 0000000..014f436
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketContext.java
@@ -0,0 +1,66 @@
+/*
+ * 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.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualPacketContext;
+import org.onosproject.net.packet.DefaultPacketContext;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+
+/**
+ *Default implementation of a virtual packet context.
+ */
+public class DefaultVirtualPacketContext extends DefaultPacketContext
+        implements VirtualPacketContext {
+
+    private NetworkId networkId;
+    private DefaultVirtualPacketProvider dvpp;
+
+    /**
+     * 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
+     * @param networkId virtual network ID where this context is handled
+     * @param dvpp  pointer to default virtual packet provider
+     */
+
+    protected DefaultVirtualPacketContext(long time, InboundPacket inPkt,
+                                          OutboundPacket outPkt, boolean block,
+                                          NetworkId networkId,
+                                          DefaultVirtualPacketProvider dvpp) {
+        super(time, inPkt, outPkt, block);
+
+        this.networkId = networkId;
+        this.dvpp = dvpp;
+    }
+
+    @Override
+    public void send() {
+        if (!this.block()) {
+            dvpp.send(this);
+        }
+    }
+
+    @Override
+    public NetworkId networkId() {
+        return networkId;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketProvider.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketProvider.java
new file mode 100644
index 0000000..9048954
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketProvider.java
@@ -0,0 +1,421 @@
+/*
+ * 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.Sets;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.onlab.packet.Ethernet;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+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.VirtualNetworkAdminService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkListener;
+import org.onosproject.incubator.net.virtual.VirtualPacketContext;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualPacketProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualPacketProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+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.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+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.HashSet;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+@Component(service = VirtualPacketProvider.class)
+public class DefaultVirtualPacketProvider extends AbstractVirtualProvider
+        implements VirtualPacketProvider {
+
+    private static final int PACKET_PROCESSOR_PRIORITY = 1;
+    private static final PacketPriority VIRTUAL_PACKET_PRIORITY = PacketPriority.REACTIVE;
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected VirtualNetworkAdminService vnaService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected VirtualProviderRegistryService providerRegistryService;
+
+    private final VirtualNetworkListener virtualNetListener = new InternalVirtualNetworkListener();
+
+    private InternalPacketProcessor processor = null;
+
+    private Set<NetworkId> networkIdSet = Sets.newConcurrentHashSet();
+
+    private ApplicationId appId;
+
+    /**
+     * Creates a provider with the supplied identifier.
+     */
+    public DefaultVirtualPacketProvider() {
+        super(new ProviderId("virtual-packet", "org.onosproject.virtual.virtual-packet"));
+    }
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication("org.onosproject.virtual.virtual-packet");
+        providerRegistryService.registerProvider(this);
+        vnaService.addListener(virtualNetListener);
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+
+        providerRegistryService.unregisterProvider(this);
+        vnaService.removeListener(virtualNetListener);
+
+        log.info("Stopped");
+    }
+
+    @Modified
+    protected void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+    }
+
+
+    @Override
+    public void emit(NetworkId networkId, OutboundPacket packet) {
+       devirtualize(networkId, packet)
+               .forEach(outboundPacket -> packetService.emit(outboundPacket));
+    }
+
+    /**
+     * Just for test.
+     */
+    protected void startPacketHandling() {
+        processor = new InternalPacketProcessor();
+        packetService.addProcessor(processor, PACKET_PROCESSOR_PRIORITY);
+    }
+
+    /**
+     * Send the outbound packet of a virtual context.
+     * This method is designed to support Context's send() method that invoked
+     * by applications.
+     * See {@link org.onosproject.net.packet.PacketContext}
+     *
+     * @param virtualPacketContext virtual packet context
+     */
+    protected void send(VirtualPacketContext virtualPacketContext) {
+        devirtualizeContext(virtualPacketContext)
+                .forEach(outboundPacket -> packetService.emit(outboundPacket));
+    }
+
+    /**
+     * Translate the requested physical PacketContext into a virtual PacketContext.
+     * See {@link org.onosproject.net.packet.PacketContext}
+     *
+     * @param context A physical PacketContext be translated
+     * @return A translated virtual PacketContext
+     */
+    private VirtualPacketContext virtualize(PacketContext context) {
+
+        VirtualPort vPort = getMappedVirtualPort(context.inPacket().receivedFrom());
+
+        if (vPort != null) {
+            ConnectPoint cp = new ConnectPoint(vPort.element().id(),
+                                               vPort.number());
+
+            Ethernet eth = context.inPacket().parsed();
+            eth.setVlanID(Ethernet.VLAN_UNTAGGED);
+
+            InboundPacket inPacket =
+                    new DefaultInboundPacket(cp, eth,
+                                             ByteBuffer.wrap(eth.serialize()));
+
+            DefaultOutboundPacket outPkt =
+                    new DefaultOutboundPacket(cp.deviceId(),
+                                              DefaultTrafficTreatment.builder().build(),
+                                              ByteBuffer.wrap(eth.serialize()));
+
+            VirtualPacketContext vContext =
+                    new DefaultVirtualPacketContext(context.time(), inPacket, outPkt,
+                                             false, vPort.networkId(),
+                                             this);
+
+            return vContext;
+        } else {
+            return null;
+        }
+
+    }
+
+    /**
+     * Find the corresponding virtual port with the physical port.
+     *
+     * @param cp the connect point for the physical network
+     * @return a virtual port
+     */
+    private VirtualPort getMappedVirtualPort(ConnectPoint cp) {
+        Set<TenantId> tIds = vnaService.getTenantIds();
+
+        Set<VirtualNetwork> vNetworks = new HashSet<>();
+        tIds.forEach(tid -> vNetworks.addAll(vnaService.getVirtualNetworks(tid)));
+
+        for (VirtualNetwork vNet : vNetworks) {
+            Set<VirtualDevice> vDevices = vnaService.getVirtualDevices(vNet.id());
+
+            Set<VirtualPort> vPorts = new HashSet<>();
+            vDevices.forEach(dev -> vPorts
+                    .addAll(vnaService.getVirtualPorts(dev.networkId(), dev.id())));
+
+            VirtualPort vPort = vPorts.stream()
+                    .filter(vp -> vp.realizedBy().equals(cp))
+                    .findFirst().orElse(null);
+
+            if (vPort != null) {
+                return vPort;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Translate the requested virtual outbound packet into
+     * a set of physical OutboundPacket.
+     * See {@link org.onosproject.net.packet.OutboundPacket}
+     *
+     * @param packet an OutboundPacket to be translated
+     * @return a set of de-virtualized (physical) OutboundPacket
+     */
+    private Set<OutboundPacket> devirtualize(NetworkId networkId, OutboundPacket packet) {
+        Set<OutboundPacket> outboundPackets = new HashSet<>();
+        Set<VirtualPort> vPorts = vnaService
+                .getVirtualPorts(networkId, packet.sendThrough());
+
+        TrafficTreatment.Builder commonTreatmentBuilder
+                = DefaultTrafficTreatment.builder();
+        packet.treatment().allInstructions().stream()
+                .filter(i -> i.type() != Instruction.Type.OUTPUT)
+                .forEach(i -> commonTreatmentBuilder.add(i));
+        TrafficTreatment commonTreatment = commonTreatmentBuilder.build();
+
+        PortNumber vOutPortNum = packet.treatment().allInstructions().stream()
+                .filter(i -> i.type() == Instruction.Type.OUTPUT)
+                .map(i -> ((Instructions.OutputInstruction) i).port())
+                .findFirst().get();
+
+        if (!vOutPortNum.isLogical()) {
+            Optional<ConnectPoint> optionalCpOut = vPorts.stream()
+                    .filter(v -> v.number().equals(vOutPortNum))
+                    .map(v -> v.realizedBy())
+                    .findFirst();
+            if (!optionalCpOut.isPresent()) {
+                log.warn("Port {} is not realized yet, in Network {}, Device {}",
+                        vOutPortNum, networkId, packet.sendThrough());
+                return outboundPackets;
+            }
+            ConnectPoint egressPoint = optionalCpOut.get();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment
+                    .builder(commonTreatment)
+                    .setOutput(egressPoint.port()).build();
+
+            OutboundPacket outboundPacket = new DefaultOutboundPacket(
+                    egressPoint.deviceId(), treatment, packet.data());
+            outboundPackets.add(outboundPacket);
+        } else {
+            if (vOutPortNum == PortNumber.FLOOD) {
+                for (VirtualPort outPort : vPorts) {
+                    ConnectPoint cpOut = outPort.realizedBy();
+                    if (cpOut != null) {
+                        TrafficTreatment treatment = DefaultTrafficTreatment
+                                .builder(commonTreatment)
+                                .setOutput(cpOut.port()).build();
+                        OutboundPacket outboundPacket = new DefaultOutboundPacket(
+                                cpOut.deviceId(), treatment, packet.data());
+                        outboundPackets.add(outboundPacket);
+                    } else {
+                        log.warn("Port {} is not realized yet, in Network {}, Device {}",
+                                outPort.number(), networkId, packet.sendThrough());
+                    }
+                }
+            }
+        }
+
+        return outboundPackets;
+    }
+
+    /**
+     * Translate the requested virtual packet context into
+     * a set of physical outbound packets.
+     *
+     * @param context A handled virtual packet context
+     */
+    private Set<OutboundPacket> devirtualizeContext(VirtualPacketContext context) {
+
+        Set<OutboundPacket> outboundPackets = new HashSet<>();
+
+        NetworkId networkId = context.networkId();
+        TrafficTreatment vTreatment = context.treatmentBuilder().build();
+        DeviceId sendThrough = context.outPacket().sendThrough();
+
+        Set<VirtualPort> vPorts = vnaService
+                .getVirtualPorts(networkId, sendThrough);
+
+        PortNumber vOutPortNum = vTreatment.allInstructions().stream()
+                .filter(i -> i.type() == Instruction.Type.OUTPUT)
+                .map(i -> ((Instructions.OutputInstruction) i).port())
+                .findFirst().get();
+
+        TrafficTreatment.Builder commonTreatmentBuilder
+                = DefaultTrafficTreatment.builder();
+        vTreatment.allInstructions().stream()
+                .filter(i -> i.type() != Instruction.Type.OUTPUT)
+                .forEach(i -> commonTreatmentBuilder.add(i));
+        TrafficTreatment commonTreatment = commonTreatmentBuilder.build();
+
+        if (!vOutPortNum.isLogical()) {
+            Optional<ConnectPoint> optionalCpOut = vPorts.stream()
+                    .filter(v -> v.number().equals(vOutPortNum))
+                    .map(v -> v.realizedBy())
+                    .findFirst();
+            if (!optionalCpOut.isPresent()) {
+                log.warn("Port {} is not realized yet, in Network {}, Device {}",
+                        vOutPortNum, networkId, sendThrough);
+                return outboundPackets;
+            }
+            ConnectPoint egressPoint = optionalCpOut.get();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment
+                    .builder(commonTreatment)
+                    .setOutput(egressPoint.port()).build();
+
+            OutboundPacket outboundPacket = new DefaultOutboundPacket(
+                    egressPoint.deviceId(), treatment, context.outPacket().data());
+            outboundPackets.add(outboundPacket);
+        } else {
+            if (vOutPortNum == PortNumber.FLOOD) {
+                Set<VirtualPort> outPorts = vPorts.stream()
+                        .filter(vp -> !vp.number().isLogical())
+                        .filter(vp -> vp.number() !=
+                                context.inPacket().receivedFrom().port())
+                        .collect(Collectors.toSet());
+
+                for (VirtualPort outPort : outPorts) {
+                    ConnectPoint cpOut = outPort.realizedBy();
+                    if (cpOut != null) {
+                        TrafficTreatment treatment = DefaultTrafficTreatment
+                                .builder(commonTreatment)
+                                .setOutput(cpOut.port()).build();
+                        OutboundPacket outboundPacket = new DefaultOutboundPacket(
+                                cpOut.deviceId(), treatment, context.outPacket().data());
+                        outboundPackets.add(outboundPacket);
+                    } else {
+                        log.warn("Port {} is not realized yet, in Network {}, Device {}",
+                                outPort.number(), networkId, sendThrough);
+                    }
+                }
+            }
+        }
+        return outboundPackets;
+    }
+
+    private final class InternalPacketProcessor implements PacketProcessor {
+
+        @Override
+        public void process(PacketContext context) {
+            if (context.isHandled()) {
+                return;
+            }
+            VirtualPacketContext vContexts = virtualize(context);
+
+            if (vContexts == null) {
+                return;
+            }
+
+            VirtualPacketProviderService service =
+                    (VirtualPacketProviderService) providerRegistryService
+                            .getProviderService(vContexts.networkId(),
+                                                VirtualPacketProvider.class);
+            if (service != null) {
+                service.processPacket(vContexts);
+            }
+        }
+    }
+
+    private class InternalVirtualNetworkListener implements VirtualNetworkListener {
+
+        @Override
+        public void event(VirtualNetworkEvent event) {
+            switch (event.type()) {
+                case NETWORK_ADDED:
+                    if (networkIdSet.isEmpty()) {
+                        processor = new InternalPacketProcessor();
+                        packetService.addProcessor(processor, PACKET_PROCESSOR_PRIORITY);
+                        log.info("Packet processor {} for virtual network is added.", processor.getClass().getName());
+                    }
+                    networkIdSet.add(event.subject());
+                    break;
+
+                case NETWORK_REMOVED:
+                    networkIdSet.remove(event.subject());
+                    if (networkIdSet.isEmpty()) {
+                        packetService.removeProcessor(processor);
+                        log.info("Packet processor {} for virtual network is removed.", processor.getClass().getName());
+                        processor = null;
+                    }
+                    break;
+
+                default:
+                    // do nothing
+                    break;
+            }
+        }
+    }
+
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManager.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManager.java
new file mode 100644
index 0000000..ebd87ea
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManager.java
@@ -0,0 +1,168 @@
+/*
+ * 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 com.google.common.collect.ImmutableSet;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.provider.VirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderId;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Implementation of the virtual provider registry and providerService registry service.
+ */
+@Component(service = VirtualProviderRegistryService.class)
+public class VirtualProviderManager implements VirtualProviderRegistryService {
+
+    private final Map<ProviderId, VirtualProvider> providers = new HashMap<>();
+    private final Map<ProviderId, VirtualProviderService> servicesWithProvider = new HashMap<>();
+    private final Map<String, VirtualProvider> providersByScheme = new HashMap<>();
+    private final Map<NetworkId, Set<VirtualProviderService>> servicesByNetwork = new HashMap<>();
+    private static Logger log = LoggerFactory.getLogger(VirtualProviderManager.class);
+
+    @Override
+    public synchronized void registerProvider(VirtualProvider virtualProvider) {
+        checkNotNull(virtualProvider, "Provider cannot be null");
+        checkState(!providers.containsKey(virtualProvider.id()),
+                   "Provider %s already registered", virtualProvider.id());
+
+        // If the provider is a primary one, check for a conflict.
+        ProviderId pid = virtualProvider.id();
+        checkState(pid.isAncillary() || !providersByScheme.containsKey(pid.scheme()),
+                   "A primary provider with id %s is already registered",
+                   providersByScheme.get(pid.scheme()));
+
+        providers.put(virtualProvider.id(), virtualProvider);
+
+        // Register the provider by URI scheme only if it is not ancillary.
+        if (!pid.isAncillary()) {
+            providersByScheme.put(pid.scheme(), virtualProvider);
+        }
+    }
+
+    @Override
+    public synchronized void unregisterProvider(VirtualProvider virtualProvider) {
+        checkNotNull(virtualProvider, "Provider cannot be null");
+
+        //TODO: invalidate provider services which subscribe the provider
+        providers.remove(virtualProvider.id());
+
+        if (!virtualProvider.id().isAncillary()) {
+            providersByScheme.remove(virtualProvider.id().scheme());
+        }
+    }
+
+    @Override
+    public synchronized void
+    registerProviderService(NetworkId networkId,
+                            VirtualProviderService virtualProviderService) {
+        Set<VirtualProviderService> services =
+                servicesByNetwork.computeIfAbsent(networkId, k -> new HashSet<>());
+
+        services.add(virtualProviderService);
+    }
+
+    @Override
+    public synchronized void
+    unregisterProviderService(NetworkId networkId,
+                              VirtualProviderService virtualProviderService) {
+        Set<VirtualProviderService> services = servicesByNetwork.get(networkId);
+
+        if (services != null) {
+            services.remove(virtualProviderService);
+        }
+    }
+
+    @Override
+    public synchronized Set<ProviderId> getProviders() {
+        return ImmutableSet.copyOf(providers.keySet());
+    }
+
+    @Override
+    public Set<ProviderId> getProvidersByService(VirtualProviderService
+                                                             virtualProviderService) {
+        Class clazz = getProviderClass(virtualProviderService);
+
+        return ImmutableSet.copyOf(providers.values().stream()
+                                           .filter(clazz::isInstance)
+                                           .map(VirtualProvider::id)
+                                           .collect(Collectors.toSet()));
+    }
+
+    @Override
+    public synchronized VirtualProvider getProvider(ProviderId providerId) {
+        return providers.get(providerId);
+    }
+
+    @Override
+    public synchronized VirtualProvider getProvider(DeviceId deviceId) {
+        return providersByScheme.get(deviceId.uri().getScheme());
+    }
+
+    @Override
+    public synchronized VirtualProvider getProvider(String scheme) {
+        return providersByScheme.get(scheme);
+    }
+
+    @Override
+    public synchronized VirtualProviderService
+    getProviderService(NetworkId networkId, Class<? extends VirtualProvider> providerClass) {
+        Set<VirtualProviderService> services = servicesByNetwork.get(networkId);
+
+        if (services == null) {
+            return null;
+        }
+
+        return services.stream()
+                .filter(s -> getProviderClass(s).equals(providerClass))
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Returns the class type of parameter type.
+     * More specifically, it returns the class type of provider service's provider type.
+     *
+     * @param service a virtual provider service
+     * @return the class type of provider service of the service
+     */
+    private Class getProviderClass(VirtualProviderService service) {
+       String className = service.getClass().getGenericSuperclass().getTypeName();
+       String pramType = className.split("<")[1].split(">")[0];
+
+        try {
+            return Class.forName(pramType);
+        } catch (ClassNotFoundException e) {
+            log.warn("getProviderClass()", e);
+        }
+
+        return null;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/package-info.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/package-info.java
new file mode 100644
index 0000000..1d9646f
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Network virtualization provider implementations.
+ */
+package org.onosproject.incubator.net.virtual.impl.provider;
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/TenantWebResource.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/TenantWebResource.java
new file mode 100644
index 0000000..768c3b9
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/TenantWebResource.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2018-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.rest;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.rest.AbstractWebResource;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.onlab.util.Tools.readTreeFromStream;
+
+/**
+ * Query and manage tenants of virtual networks.
+ */
+@Path("tenants")
+public class TenantWebResource extends AbstractWebResource {
+
+    private static final String MISSING_TENANTID = "Missing tenant identifier";
+    private static final String TENANTID_NOT_FOUND = "Tenant identifier not found";
+    private static final String INVALID_TENANTID = "Invalid tenant identifier ";
+
+    @Context
+    private UriInfo uriInfo;
+
+    private final VirtualNetworkAdminService vnetAdminService = get(VirtualNetworkAdminService.class);
+
+    /**
+     * Returns all tenant identifiers.
+     *
+     * @return 200 OK with set of tenant identifiers
+     * @onos.rsModel TenantIds
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getVirtualNetworkTenantIds() {
+        Iterable<TenantId> tenantIds = vnetAdminService.getTenantIds();
+        return ok(encodeArray(TenantId.class, "tenants", tenantIds)).build();
+    }
+
+    /**
+     * Creates a tenant with the given tenant identifier.
+     *
+     * @param stream TenantId JSON stream
+     * @return status of the request - CREATED if the JSON is correct,
+     * BAD_REQUEST if the JSON is invalid
+     * @onos.rsModel TenantId
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response addTenantId(InputStream stream) {
+        try {
+            final TenantId tid = getTenantIdFromJsonStream(stream);
+            vnetAdminService.registerTenantId(tid);
+            final TenantId resultTid = getExistingTenantId(vnetAdminService, tid);
+            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
+                    .path("tenants")
+                    .path(resultTid.id());
+            return Response
+                    .created(locationBuilder.build())
+                    .build();
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Removes the specified tenant with the specified tenant identifier.
+     *
+     * @param tenantId tenant identifier
+     * @return 204 NO CONTENT
+     */
+    @DELETE
+    @Path("{tenantId}")
+    public Response removeTenantId(@PathParam("tenantId") String tenantId) {
+        final TenantId tid = TenantId.tenantId(tenantId);
+        final TenantId existingTid = getExistingTenantId(vnetAdminService, tid);
+        vnetAdminService.unregisterTenantId(existingTid);
+        return Response.noContent().build();
+    }
+
+    /**
+     * Gets the tenant identifier from the JSON stream.
+     *
+     * @param stream TenantId JSON stream
+     * @return TenantId
+     * @throws IOException if unable to parse the request
+     */
+    private TenantId getTenantIdFromJsonStream(InputStream stream) throws IOException {
+        ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
+        JsonNode specifiedTenantId = jsonTree.get("id");
+
+        if (specifiedTenantId == null) {
+            throw new IllegalArgumentException(MISSING_TENANTID);
+        }
+        return TenantId.tenantId(specifiedTenantId.asText());
+    }
+
+    /**
+     * Get the matching tenant identifier from existing tenant identifiers in system.
+     *
+     * @param vnetAdminSvc virtual network administration service
+     * @param tidIn        tenant identifier
+     * @return TenantId
+     */
+    protected static TenantId getExistingTenantId(VirtualNetworkAdminService vnetAdminSvc,
+                                                TenantId tidIn) {
+        return vnetAdminSvc
+                .getTenantIds()
+                .stream()
+                .filter(tenantId -> tenantId.equals(tidIn))
+                .findFirst()
+                .orElseThrow(() -> new ItemNotFoundException(TENANTID_NOT_FOUND));
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebApplication.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebApplication.java
new file mode 100644
index 0000000..4a80dbe
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebApplication.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018-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.rest;
+
+import org.onlab.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * Virtual network REST APIs web application.
+ */
+public class VirtualNetworkWebApplication extends AbstractWebApplication {
+    @Override
+    public Set<Class<?>> getClasses() {
+        return getClasses(
+                TenantWebResource.class,
+                VirtualNetworkWebResource.class
+        );
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebResource.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebResource.java
new file mode 100644
index 0000000..e8696c3
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebResource.java
@@ -0,0 +1,487 @@
+/*
+ * Copyright 2018-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.rest;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+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.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.rest.AbstractWebResource;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.onlab.util.Tools.readTreeFromStream;
+
+/**
+ * Query and Manage Virtual Network elements.
+ */
+@Path("vnets")
+public class VirtualNetworkWebResource extends AbstractWebResource {
+
+    private static final String MISSING_FIELD = "Missing ";
+    private static final String INVALID_FIELD = "Invalid ";
+
+    private final VirtualNetworkAdminService vnetAdminService = get(VirtualNetworkAdminService.class);
+    private final VirtualNetworkService vnetService = get(VirtualNetworkService.class);
+
+    @Context
+    private UriInfo uriInfo;
+
+    // VirtualNetwork
+
+    /**
+     * Returns all virtual networks.
+     *
+     * @return 200 OK with set of virtual networks
+     * @onos.rsModel VirtualNetworks
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getVirtualNetworks() {
+        Set<TenantId> tenantIds = vnetAdminService.getTenantIds();
+        List<VirtualNetwork> allVnets = tenantIds.stream()
+                .map(tenantId -> vnetService.getVirtualNetworks(tenantId))
+                .flatMap(Collection::stream)
+                .collect(Collectors.toList());
+        return ok(encodeArray(VirtualNetwork.class, "vnets", allVnets)).build();
+    }
+
+    /**
+     * Returns the virtual networks with the specified tenant identifier.
+     *
+     * @param tenantId tenant identifier
+     * @return 200 OK with a virtual network, 404 not found
+     * @onos.rsModel VirtualNetworks
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{tenantId}")
+    public Response getVirtualNetworkById(@PathParam("tenantId") String tenantId) {
+        final TenantId existingTid = TenantWebResource.getExistingTenantId(vnetAdminService,
+                                                                           TenantId.tenantId(tenantId));
+        Set<VirtualNetwork> vnets = vnetService.getVirtualNetworks(existingTid);
+        return ok(encodeArray(VirtualNetwork.class, "vnets", vnets)).build();
+    }
+
+    /**
+     * Creates a virtual network from the JSON input stream.
+     *
+     * @param stream tenant identifier JSON stream
+     * @return status of the request - CREATED if the JSON is correct,
+     * BAD_REQUEST if the JSON is invalid
+     * @onos.rsModel TenantId
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createVirtualNetwork(InputStream stream) {
+        try {
+            final TenantId tid = TenantId.tenantId(getFromJsonStream(stream, "id").asText());
+            VirtualNetwork newVnet = vnetAdminService.createVirtualNetwork(tid);
+            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
+                    .path("vnets")
+                    .path(newVnet.id().toString());
+            return Response
+                    .created(locationBuilder.build())
+                    .build();
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Removes the virtual network with the specified network identifier.
+     *
+     * @param networkId network identifier
+     * @return 204 NO CONTENT
+     */
+    @DELETE
+    @Path("{networkId}")
+    public Response removeVirtualNetwork(@PathParam("networkId") long networkId) {
+        NetworkId nid = NetworkId.networkId(networkId);
+        vnetAdminService.removeVirtualNetwork(nid);
+        return Response.noContent().build();
+    }
+
+    // VirtualDevice
+
+    /**
+     * Returns all virtual network devices in a virtual network.
+     *
+     * @param networkId network identifier
+     * @return 200 OK with set of virtual devices, 404 not found
+     * @onos.rsModel VirtualDevices
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{networkId}/devices")
+    public Response getVirtualDevices(@PathParam("networkId") long networkId) {
+        NetworkId nid = NetworkId.networkId(networkId);
+        Set<VirtualDevice> vdevs = vnetService.getVirtualDevices(nid);
+        return ok(encodeArray(VirtualDevice.class, "devices", vdevs)).build();
+    }
+
+    /**
+     * Creates a virtual device from the JSON input stream.
+     *
+     * @param networkId network identifier
+     * @param stream    virtual device JSON stream
+     * @return status of the request - CREATED if the JSON is correct,
+     * BAD_REQUEST if the JSON is invalid
+     * @onos.rsModel VirtualDevice
+     */
+    @POST
+    @Path("{networkId}/devices")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createVirtualDevice(@PathParam("networkId") long networkId,
+                                        InputStream stream) {
+        try {
+            ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
+            final VirtualDevice vdevReq = codec(VirtualDevice.class).decode(jsonTree, this);
+            JsonNode specifiedNetworkId = jsonTree.get("networkId");
+            if (specifiedNetworkId == null || specifiedNetworkId.asLong() != (networkId)) {
+                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
+            }
+            final VirtualDevice vdevRes = vnetAdminService.createVirtualDevice(vdevReq.networkId(),
+                                                                               vdevReq.id());
+            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
+                    .path("vnets").path(specifiedNetworkId.asText())
+                    .path("devices").path(vdevRes.id().toString());
+            return Response
+                    .created(locationBuilder.build())
+                    .build();
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Removes the virtual network device from the virtual network.
+     *
+     * @param networkId network identifier
+     * @param deviceId  device identifier
+     * @return 204 NO CONTENT
+     */
+    @DELETE
+    @Path("{networkId}/devices/{deviceId}")
+    public Response removeVirtualDevice(@PathParam("networkId") long networkId,
+                                        @PathParam("deviceId") String deviceId) {
+        NetworkId nid = NetworkId.networkId(networkId);
+        DeviceId did = DeviceId.deviceId(deviceId);
+        vnetAdminService.removeVirtualDevice(nid, did);
+        return Response.noContent().build();
+    }
+
+    // VirtualPort
+
+    /**
+     * Returns all virtual network ports in a virtual device in a virtual network.
+     *
+     * @param networkId network identifier
+     * @param deviceId  virtual device identifier
+     * @return 200 OK with set of virtual ports, 404 not found
+     * @onos.rsModel VirtualPorts
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{networkId}/devices/{deviceId}/ports")
+    public Response getVirtualPorts(@PathParam("networkId") long networkId,
+                                    @PathParam("deviceId") String deviceId) {
+        NetworkId nid = NetworkId.networkId(networkId);
+        Iterable<VirtualPort> vports = vnetService.getVirtualPorts(nid, DeviceId.deviceId(deviceId));
+        return ok(encodeArray(VirtualPort.class, "ports", vports)).build();
+    }
+
+    /**
+     * Creates a virtual network port in a virtual device in a virtual network.
+     *
+     * @param networkId    network identifier
+     * @param virtDeviceId virtual device identifier
+     * @param stream       virtual port JSON stream
+     * @return status of the request - CREATED if the JSON is correct,
+     * BAD_REQUEST if the JSON is invalid
+     * @onos.rsModel VirtualPort
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{networkId}/devices/{deviceId}/ports")
+    public Response createVirtualPort(@PathParam("networkId") long networkId,
+                                      @PathParam("deviceId") String virtDeviceId,
+                                      InputStream stream) {
+        try {
+            ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
+//            final VirtualPort vportReq = codec(VirtualPort.class).decode(jsonTree, this);
+            JsonNode specifiedNetworkId = jsonTree.get("networkId");
+            JsonNode specifiedDeviceId = jsonTree.get("deviceId");
+            if (specifiedNetworkId == null || specifiedNetworkId.asLong() != (networkId)) {
+                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
+            }
+            if (specifiedDeviceId == null || !specifiedDeviceId.asText().equals(virtDeviceId)) {
+                throw new IllegalArgumentException(INVALID_FIELD + "deviceId");
+            }
+            JsonNode specifiedPortNum = jsonTree.get("portNum");
+            JsonNode specifiedPhysDeviceId = jsonTree.get("physDeviceId");
+            JsonNode specifiedPhysPortNum = jsonTree.get("physPortNum");
+            final NetworkId nid = NetworkId.networkId(networkId);
+            DeviceId vdevId = DeviceId.deviceId(virtDeviceId);
+
+            ConnectPoint realizedBy = new ConnectPoint(DeviceId.deviceId(specifiedPhysDeviceId.asText()),
+                                              PortNumber.portNumber(specifiedPhysPortNum.asText()));
+            VirtualPort vport = vnetAdminService.createVirtualPort(nid, vdevId,
+                                    PortNumber.portNumber(specifiedPortNum.asText()), realizedBy);
+            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
+                    .path("vnets").path(specifiedNetworkId.asText())
+                    .path("devices").path(specifiedDeviceId.asText())
+                    .path("ports").path(vport.number().toString());
+            return Response
+                    .created(locationBuilder.build())
+                    .build();
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Removes the virtual network port from the virtual device in a virtual network.
+     *
+     * @param networkId network identifier
+     * @param deviceId  virtual device identifier
+     * @param portNum   virtual port number
+     * @return 204 NO CONTENT
+     */
+    @DELETE
+    @Path("{networkId}/devices/{deviceId}/ports/{portNum}")
+    public Response removeVirtualPort(@PathParam("networkId") long networkId,
+                                      @PathParam("deviceId") String deviceId,
+                                      @PathParam("portNum") long portNum) {
+        NetworkId nid = NetworkId.networkId(networkId);
+        vnetAdminService.removeVirtualPort(nid, DeviceId.deviceId(deviceId),
+                                           PortNumber.portNumber(portNum));
+        return Response.noContent().build();
+    }
+
+    // VirtualLink
+
+    /**
+     * Returns all virtual network links in a virtual network.
+     *
+     * @param networkId network identifier
+     * @return 200 OK with set of virtual network links
+     * @onos.rsModel VirtualLinks
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{networkId}/links")
+    public Response getVirtualLinks(@PathParam("networkId") long networkId) {
+        NetworkId nid = NetworkId.networkId(networkId);
+        Set<VirtualLink> vlinks = vnetService.getVirtualLinks(nid);
+        return ok(encodeArray(VirtualLink.class, "links", vlinks)).build();
+    }
+
+    /**
+     * Creates a virtual network link from the JSON input stream.
+     *
+     * @param networkId network identifier
+     * @param stream    virtual link JSON stream
+     * @return status of the request - CREATED if the JSON is correct,
+     * BAD_REQUEST if the JSON is invalid
+     * @onos.rsModel VirtualLink
+     */
+    @POST
+    @Path("{networkId}/links")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createVirtualLink(@PathParam("networkId") long networkId,
+                                      InputStream stream) {
+        try {
+            ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
+            JsonNode specifiedNetworkId = jsonTree.get("networkId");
+            if (specifiedNetworkId == null || specifiedNetworkId.asLong() != (networkId)) {
+                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
+            }
+            final VirtualLink vlinkReq = codec(VirtualLink.class).decode(jsonTree, this);
+            vnetAdminService.createVirtualLink(vlinkReq.networkId(),
+                                               vlinkReq.src(), vlinkReq.dst());
+            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
+                    .path("vnets").path(specifiedNetworkId.asText())
+                    .path("links");
+            return Response
+                    .created(locationBuilder.build())
+                    .build();
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Removes the virtual network link from the JSON input stream.
+     *
+     * @param networkId network identifier
+     * @param stream    virtual link JSON stream
+     * @return 204 NO CONTENT
+     * @onos.rsModel VirtualLink
+     */
+    @DELETE
+    @Path("{networkId}/links")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response removeVirtualLink(@PathParam("networkId") long networkId,
+                                      InputStream stream) {
+        try {
+            ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
+            JsonNode specifiedNetworkId = jsonTree.get("networkId");
+            if (specifiedNetworkId != null &&
+                    specifiedNetworkId.asLong() != (networkId)) {
+                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
+            }
+            final VirtualLink vlinkReq = codec(VirtualLink.class).decode(jsonTree, this);
+            vnetAdminService.removeVirtualLink(vlinkReq.networkId(),
+                                               vlinkReq.src(), vlinkReq.dst());
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+
+        return Response.noContent().build();
+    }
+
+    /**
+     * Returns all virtual network hosts in a virtual network.
+     *
+     * @param networkId network identifier
+     * @return 200 OK with set of virtual network hosts
+     * @onos.rsModel VirtualHosts
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{networkId}/hosts")
+    public Response getVirtualHosts(@PathParam("networkId") long networkId) {
+        NetworkId nid = NetworkId.networkId(networkId);
+        Set<VirtualHost> vhosts = vnetService.getVirtualHosts(nid);
+        return ok(encodeArray(VirtualHost.class, "hosts", vhosts)).build();
+    }
+
+    /**
+     * Creates a virtual network host from the JSON input stream.
+     *
+     * @param networkId network identifier
+     * @param stream    virtual host JSON stream
+     * @return status of the request - CREATED if the JSON is correct,
+     * BAD_REQUEST if the JSON is invalid
+     * @onos.rsModel VirtualHostPut
+     */
+    @POST
+    @Path("{networkId}/hosts")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createVirtualHost(@PathParam("networkId") long networkId,
+                                      InputStream stream) {
+        try {
+            ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
+            JsonNode specifiedNetworkId = jsonTree.get("networkId");
+            if (specifiedNetworkId == null || specifiedNetworkId.asLong() != (networkId)) {
+                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
+            }
+            final VirtualHost vhostReq = codec(VirtualHost.class).decode(jsonTree, this);
+            vnetAdminService.createVirtualHost(vhostReq.networkId(), vhostReq.id(),
+                                               vhostReq.mac(), vhostReq.vlan(),
+                                               vhostReq.location(), vhostReq.ipAddresses());
+            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
+                    .path("vnets").path(specifiedNetworkId.asText())
+                    .path("hosts");
+            return Response
+                    .created(locationBuilder.build())
+                    .build();
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Removes the virtual network host from the JSON input stream.
+     *
+     * @param networkId network identifier
+     * @param stream    virtual host JSON stream
+     * @return 204 NO CONTENT
+     * @onos.rsModel VirtualHost
+     */
+    @DELETE
+    @Path("{networkId}/hosts")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response removeVirtualHost(@PathParam("networkId") long networkId,
+                                      InputStream stream) {
+        try {
+            ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
+            JsonNode specifiedNetworkId = jsonTree.get("networkId");
+            if (specifiedNetworkId != null &&
+                    specifiedNetworkId.asLong() != (networkId)) {
+                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
+            }
+            final VirtualHost vhostReq = codec(VirtualHost.class).decode(jsonTree, this);
+            vnetAdminService.removeVirtualHost(vhostReq.networkId(), vhostReq.id());
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+
+        return Response.noContent().build();
+    }
+
+    /**
+     * Get the tenant identifier from the JSON stream.
+     *
+     * @param stream        TenantId JSON stream
+     * @param jsonFieldName field name
+     * @return JsonNode
+     * @throws IOException if unable to parse the request
+     */
+    private JsonNode getFromJsonStream(InputStream stream, String jsonFieldName) throws IOException {
+        ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
+        JsonNode jsonNode = jsonTree.get(jsonFieldName);
+
+        if (jsonNode == null) {
+            throw new IllegalArgumentException(MISSING_FIELD + jsonFieldName);
+        }
+        return jsonNode;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/package-info.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/package-info.java
new file mode 100644
index 0000000..0b8a711
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/rest/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2018-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.
+ */
+
+/**
+ * REST API of the virtual network subsystem.
+ */
+package org.onosproject.incubator.net.virtual.rest;
\ No newline at end of file
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/AbstractVirtualStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/AbstractVirtualStore.java
new file mode 100644
index 0000000..73f5bdb
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/AbstractVirtualStore.java
@@ -0,0 +1,82 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.collect.Maps;
+import org.onosproject.event.Event;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualStore;
+import org.onosproject.store.StoreDelegate;
+
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Base implementation of a virtual store.
+ */
+public class AbstractVirtualStore<E extends Event, D extends StoreDelegate<E>>
+        implements VirtualStore<E, D> {
+
+    protected Map<NetworkId, D> delegateMap = Maps.newConcurrentMap();
+
+    @Override
+    public void setDelegate(NetworkId networkId, D delegate) {
+        checkState(delegateMap.get(networkId) == null
+                           || delegateMap.get(networkId) == delegate,
+                   "Store delegate already set");
+
+        delegateMap.putIfAbsent(networkId, delegate);
+    }
+
+    @Override
+    public void unsetDelegate(NetworkId networkId, D delegate) {
+        if (delegateMap.get(networkId) == delegate) {
+            delegateMap.remove(networkId, delegate);
+        }
+    }
+
+    @Override
+    public boolean hasDelegate(NetworkId networkId) {
+        return delegateMap.get(networkId) != null;
+    }
+
+    /**
+     * Notifies the delegate with the specified event.
+     *
+     * @param networkId a virtual network identifier
+     * @param event event to delegate
+     */
+    protected void notifyDelegate(NetworkId networkId, E event) {
+        if (delegateMap.get(networkId) != null) {
+            delegateMap.get(networkId).notify(event);
+        }
+    }
+
+    /**
+     * Notifies the delegate with the specified list of events.
+     *
+     * @param networkId a virtual network identifier
+     * @param events list of events to delegate
+     */
+    protected void notifyDelegate(NetworkId networkId, List<E> events) {
+        for (E event: events) {
+            notifyDelegate(networkId, event);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/ConsistentVirtualDeviceMastershipStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/ConsistentVirtualDeviceMastershipStore.java
new file mode 100644
index 0000000..408ce9c
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/ConsistentVirtualDeviceMastershipStore.java
@@ -0,0 +1,467 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.Leadership;
+import org.onosproject.cluster.LeadershipAdminService;
+import org.onosproject.cluster.LeadershipEvent;
+import org.onosproject.cluster.LeadershipEventListener;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.cluster.RoleInfo;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkMastershipStore;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipInfo;
+import org.onosproject.mastership.MastershipStoreDelegate;
+import org.onosproject.mastership.MastershipTerm;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
+import org.onosproject.store.cluster.messaging.MessageSubject;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.Serializer;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.mastership.MastershipEvent.Type.BACKUPS_CHANGED;
+import static org.onosproject.mastership.MastershipEvent.Type.MASTER_CHANGED;
+import static org.onosproject.mastership.MastershipEvent.Type.SUSPENDED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+@Component(immediate = true, enabled = false, service = VirtualNetworkMastershipStore.class)
+public class ConsistentVirtualDeviceMastershipStore
+        extends AbstractVirtualStore<MastershipEvent, MastershipStoreDelegate>
+        implements VirtualNetworkMastershipStore {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected LeadershipService leadershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected LeadershipAdminService leadershipAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ClusterCommunicationService clusterCommunicator;
+
+    private NodeId localNodeId;
+
+    private static final MessageSubject ROLE_RELINQUISH_SUBJECT =
+            new MessageSubject("virtual-mastership-store-device-role-relinquish");
+
+    private static final Pattern DEVICE_MASTERSHIP_TOPIC_PATTERN =
+            Pattern.compile("vnet:(.*),device:(.*)");
+
+    private ExecutorService eventHandler;
+    private ExecutorService messageHandlingExecutor;
+    private ScheduledExecutorService transferExecutor;
+    private final LeadershipEventListener leadershipEventListener =
+            new InternalDeviceMastershipEventListener();
+
+    private static final String NODE_ID_NULL = "Node ID cannot be null";
+    private static final String NETWORK_ID_NULL = "Network ID cannot be null";
+    private static final String DEVICE_ID_NULL = "Device ID cannot be null";
+    private static final int WAIT_BEFORE_MASTERSHIP_HANDOFF_MILLIS = 3000;
+
+    public static final Serializer SERIALIZER = Serializer.using(
+            KryoNamespace.newBuilder()
+                    .register(KryoNamespaces.API)
+                    .register(MastershipRole.class)
+                    .register(MastershipEvent.class)
+                    .register(MastershipEvent.Type.class)
+                    .register(VirtualDeviceId.class)
+                    .build("VirtualMastershipStore"));
+
+    @Activate
+    public void activate() {
+        eventHandler = Executors.newSingleThreadExecutor(
+                groupedThreads("onos/store/virtual/mastership", "event-handler", log));
+
+        messageHandlingExecutor =
+                Executors.newSingleThreadExecutor(
+                        groupedThreads("onos/store/virtual/mastership", "message-handler", log));
+        transferExecutor =
+                Executors.newSingleThreadScheduledExecutor(
+                        groupedThreads("onos/store/virtual/mastership", "mastership-transfer-executor", log));
+        clusterCommunicator.addSubscriber(ROLE_RELINQUISH_SUBJECT,
+                                          SERIALIZER::decode,
+                                          this::relinquishLocalRole,
+                                          SERIALIZER::encode,
+                                          messageHandlingExecutor);
+        localNodeId = clusterService.getLocalNode().id();
+        leadershipService.addListener(leadershipEventListener);
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        clusterCommunicator.removeSubscriber(ROLE_RELINQUISH_SUBJECT);
+        leadershipService.removeListener(leadershipEventListener);
+        messageHandlingExecutor.shutdown();
+        transferExecutor.shutdown();
+        eventHandler.shutdown();
+        log.info("Stopped");
+    }
+
+    @Override
+    public CompletableFuture<MastershipRole> requestRole(NetworkId networkId,
+                                                         DeviceId deviceId) {
+        checkArgument(networkId != null, NETWORK_ID_NULL);
+        checkArgument(deviceId != null, DEVICE_ID_NULL);
+
+        String leadershipTopic = createDeviceMastershipTopic(networkId, deviceId);
+        Leadership leadership = leadershipService.runForLeadership(leadershipTopic);
+        return CompletableFuture
+                .completedFuture(localNodeId.equals(leadership.leaderNodeId()) ?
+                                         MastershipRole.MASTER : MastershipRole.STANDBY);
+    }
+
+    @Override
+    public MastershipRole getRole(NetworkId networkId, NodeId nodeId, DeviceId deviceId) {
+        checkArgument(networkId != null, NETWORK_ID_NULL);
+        checkArgument(nodeId != null, NODE_ID_NULL);
+        checkArgument(deviceId != null, DEVICE_ID_NULL);
+
+        String leadershipTopic = createDeviceMastershipTopic(networkId, deviceId);
+        Leadership leadership = leadershipService.getLeadership(leadershipTopic);
+        NodeId leader = leadership == null ? null : leadership.leaderNodeId();
+        List<NodeId> candidates = leadership == null ?
+                ImmutableList.of() : ImmutableList.copyOf(leadership.candidates());
+        return Objects.equal(nodeId, leader) ?
+                MastershipRole.MASTER : candidates.contains(nodeId) ?
+                MastershipRole.STANDBY : MastershipRole.NONE;
+    }
+
+    @Override
+    public NodeId getMaster(NetworkId networkId, DeviceId deviceId) {
+        checkArgument(deviceId != null, DEVICE_ID_NULL);
+
+        return leadershipService.getLeader(createDeviceMastershipTopic(networkId, deviceId));
+    }
+
+    @Override
+    public RoleInfo getNodes(NetworkId networkId, DeviceId deviceId) {
+        checkArgument(networkId != null, NETWORK_ID_NULL);
+        checkArgument(deviceId != null, DEVICE_ID_NULL);
+        Leadership leadership = leadershipService.getLeadership(createDeviceMastershipTopic(networkId, deviceId));
+        return new RoleInfo(leadership.leaderNodeId(), leadership.candidates());
+    }
+
+    @Override
+    public MastershipInfo getMastership(NetworkId networkId, DeviceId deviceId) {
+        checkArgument(networkId != null, NETWORK_ID_NULL);
+        checkArgument(deviceId != null, DEVICE_ID_NULL);
+        Leadership leadership = leadershipService.getLeadership(createDeviceMastershipTopic(networkId, deviceId));
+        return buildMastershipFromLeadership(leadership);
+    }
+
+    @Override
+    public Set<DeviceId> getDevices(NetworkId networkId, NodeId nodeId) {
+        checkArgument(networkId != null, NETWORK_ID_NULL);
+        checkArgument(nodeId != null, NODE_ID_NULL);
+
+        // FIXME This result contains REMOVED device.
+        // MastershipService cannot listen to DeviceEvent to GC removed topic,
+        // since DeviceManager depend on it.
+        // Reference count, etc. at LeadershipService layer?
+        return leadershipService
+                .ownedTopics(nodeId)
+                .stream()
+                .filter(this::isVirtualMastershipTopic)
+                .map(this::extractDeviceIdFromTopic)
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public CompletableFuture<MastershipEvent> setMaster(NetworkId networkId,
+                                                        NodeId nodeId, DeviceId deviceId) {
+        checkArgument(networkId != null, NETWORK_ID_NULL);
+        checkArgument(nodeId != null, NODE_ID_NULL);
+        checkArgument(deviceId != null, DEVICE_ID_NULL);
+
+        String leadershipTopic = createDeviceMastershipTopic(networkId, deviceId);
+        if (leadershipAdminService.promoteToTopOfCandidateList(leadershipTopic, nodeId)) {
+            transferExecutor.schedule(() -> leadershipAdminService.transferLeadership(leadershipTopic, nodeId),
+                                      WAIT_BEFORE_MASTERSHIP_HANDOFF_MILLIS, TimeUnit.MILLISECONDS);
+        }
+        return CompletableFuture.completedFuture(null);
+    }
+
+    @Override
+    public MastershipTerm getTermFor(NetworkId networkId, DeviceId deviceId) {
+        checkArgument(networkId != null, NETWORK_ID_NULL);
+        checkArgument(deviceId != null, DEVICE_ID_NULL);
+
+        String leadershipTopic = createDeviceMastershipTopic(networkId, deviceId);
+        Leadership leadership = leadershipService.getLeadership(leadershipTopic);
+        return leadership != null && leadership.leaderNodeId() != null ?
+                MastershipTerm.of(leadership.leaderNodeId(),
+                                  leadership.leader().term()) : null;
+    }
+
+    @Override
+    public CompletableFuture<MastershipEvent> setStandby(NetworkId networkId,
+                                                         NodeId nodeId,
+                                                         DeviceId deviceId) {
+        checkArgument(networkId != null, NETWORK_ID_NULL);
+        checkArgument(nodeId != null, NODE_ID_NULL);
+        checkArgument(deviceId != null, DEVICE_ID_NULL);
+
+        NodeId currentMaster = getMaster(networkId, deviceId);
+        if (!nodeId.equals(currentMaster)) {
+            return CompletableFuture.completedFuture(null);
+        }
+
+        String leadershipTopic = createDeviceMastershipTopic(networkId, deviceId);
+        List<NodeId> candidates = leadershipService.getCandidates(leadershipTopic);
+
+        NodeId newMaster = candidates.stream()
+                .filter(candidate -> !Objects.equal(nodeId, candidate))
+                .findFirst()
+                .orElse(null);
+        log.info("Transitioning to role {} for {}. Next master: {}",
+                 newMaster != null ? MastershipRole.STANDBY : MastershipRole.NONE,
+                 deviceId, newMaster);
+
+        if (newMaster != null) {
+            return setMaster(networkId, newMaster, deviceId);
+        }
+        return relinquishRole(networkId, nodeId, deviceId);
+    }
+
+    @Override
+    public CompletableFuture<MastershipEvent> relinquishRole(NetworkId networkId,
+                                                             NodeId nodeId,
+                                                             DeviceId deviceId) {
+        checkArgument(networkId != null, NETWORK_ID_NULL);
+        checkArgument(nodeId != null, NODE_ID_NULL);
+        checkArgument(deviceId != null, DEVICE_ID_NULL);
+
+        if (nodeId.equals(localNodeId)) {
+            return relinquishLocalRoleByNetwork(networkId, deviceId);
+        }
+
+        log.debug("Forwarding request to relinquish "
+                          + "role for vnet {} device {} to {}", deviceId, nodeId);
+        return clusterCommunicator.sendAndReceive(
+                new VirtualDeviceId(networkId, deviceId),
+                ROLE_RELINQUISH_SUBJECT,
+                SERIALIZER::encode,
+                SERIALIZER::decode,
+                nodeId);
+    }
+
+    private CompletableFuture<MastershipEvent> relinquishLocalRoleByNetwork(NetworkId networkId,
+                                                                   DeviceId deviceId) {
+        checkArgument(networkId != null, NETWORK_ID_NULL);
+        checkArgument(deviceId != null, DEVICE_ID_NULL);
+
+        String leadershipTopic = createDeviceMastershipTopic(networkId, deviceId);
+        if (!leadershipService.getCandidates(leadershipTopic).contains(localNodeId)) {
+            return CompletableFuture.completedFuture(null);
+        }
+        MastershipEvent.Type eventType = localNodeId.equals(leadershipService.getLeader(leadershipTopic)) ?
+                MastershipEvent.Type.MASTER_CHANGED : MastershipEvent.Type.BACKUPS_CHANGED;
+        leadershipService.withdraw(leadershipTopic);
+        return CompletableFuture.completedFuture(
+            new MastershipEvent(eventType, deviceId, getMastership(networkId, deviceId)));
+    }
+
+    private CompletableFuture<MastershipEvent>
+    relinquishLocalRole(VirtualDeviceId virtualDeviceId) {
+        return relinquishLocalRoleByNetwork(virtualDeviceId.networkId,
+                                            virtualDeviceId.deviceId);
+    }
+
+    @Override
+    public void relinquishAllRole(NetworkId networkId, NodeId nodeId) {
+        // Noop. LeadershipService already takes care of detecting and purging stale locks.
+    }
+
+    private MastershipInfo buildMastershipFromLeadership(Leadership leadership) {
+        ImmutableMap.Builder<NodeId, MastershipRole> builder = ImmutableMap.builder();
+        if (leadership.leaderNodeId() != null) {
+            builder.put(leadership.leaderNodeId(), MastershipRole.MASTER);
+        }
+        leadership.candidates().forEach(nodeId -> builder.put(nodeId, MastershipRole.STANDBY));
+        clusterService.getNodes().stream()
+            .filter(node -> !leadership.candidates().contains(node.id()))
+            .forEach(node -> builder.put(node.id(), MastershipRole.NONE));
+
+        return new MastershipInfo(
+            leadership.leader() != null ? leadership.leader().term() : 0,
+            leadership.leader() != null
+                ? Optional.of(leadership.leader().nodeId())
+                : Optional.empty(),
+            builder.build());
+    }
+
+    private class InternalDeviceMastershipEventListener
+            implements LeadershipEventListener {
+
+        @Override
+        public boolean isRelevant(LeadershipEvent event) {
+            Leadership leadership = event.subject();
+            return isVirtualMastershipTopic(leadership.topic());
+        }
+
+        @Override
+        public void event(LeadershipEvent event) {
+            eventHandler.execute(() -> handleEvent(event));
+        }
+
+        private void handleEvent(LeadershipEvent event) {
+            Leadership leadership = event.subject();
+
+            NetworkId networkId = extractNetworkIdFromTopic(leadership.topic());
+            DeviceId deviceId = extractDeviceIdFromTopic(leadership.topic());
+            MastershipInfo mastershipInfo = event.type() != LeadershipEvent.Type.SERVICE_DISRUPTED
+                ? buildMastershipFromLeadership(event.subject())
+                : new MastershipInfo();
+
+            switch (event.type()) {
+                case LEADER_AND_CANDIDATES_CHANGED:
+                    notifyDelegate(networkId, new MastershipEvent(BACKUPS_CHANGED, deviceId, mastershipInfo));
+                    notifyDelegate(networkId, new MastershipEvent(MASTER_CHANGED, deviceId, mastershipInfo));
+                    break;
+                case LEADER_CHANGED:
+                    notifyDelegate(networkId, new MastershipEvent(MASTER_CHANGED, deviceId, mastershipInfo));
+                    break;
+                case CANDIDATES_CHANGED:
+                    notifyDelegate(networkId, new MastershipEvent(BACKUPS_CHANGED, deviceId, mastershipInfo));
+                    break;
+                case SERVICE_DISRUPTED:
+                    notifyDelegate(networkId, new MastershipEvent(SUSPENDED, deviceId, mastershipInfo));
+                    break;
+                case SERVICE_RESTORED:
+                    // Do nothing, wait for updates from peers
+                    break;
+                default:
+            }
+        }
+    }
+
+    private String createDeviceMastershipTopic(NetworkId networkId, DeviceId deviceId) {
+        return String.format("vnet:%s,device:%s", networkId.toString(), deviceId.toString());
+    }
+
+    /**
+     * Returns the virtual network identifier extracted from the topic.
+     *
+     * @param topic topic to extract virtual network identifier
+     * @return an extracted virtual network identifier
+     * @throws IllegalArgumentException the topic not match with the pattern
+     * used for virtual network mastership store
+     */
+    private NetworkId extractNetworkIdFromTopic(String topic) {
+        Matcher m = DEVICE_MASTERSHIP_TOPIC_PATTERN.matcher(topic);
+        if (m.matches()) {
+            return NetworkId.networkId(Long.getLong(m.group(1)));
+        } else {
+            throw new IllegalArgumentException("Invalid virtual mastership topic: "
+                                                       + topic);
+        }
+    }
+
+    /**
+     * Returns the device identifier extracted from the topic.
+     *
+     * @param topic topic to extract device identifier
+     * @return an extracted virtual device identifier
+     * @throws IllegalArgumentException the topic not match with the pattern
+     * used for virtual network mastership store
+     */
+    private DeviceId extractDeviceIdFromTopic(String topic) {
+        Matcher m = DEVICE_MASTERSHIP_TOPIC_PATTERN.matcher(topic);
+        if (m.matches()) {
+            return DeviceId.deviceId(m.group(2));
+        } else {
+            throw new IllegalArgumentException("Invalid virtual mastership topic: "
+                                                       + topic);
+        }
+    }
+
+    /**
+     * Returns whether the topic is matched with virtual mastership store topic.
+     *
+     * @param topic topic to match
+     * @return True when the topic matched with virtual network mastership store
+     */
+    private boolean isVirtualMastershipTopic(String topic) {
+        Matcher m = DEVICE_MASTERSHIP_TOPIC_PATTERN.matcher(topic);
+        return m.matches();
+    }
+
+    /**
+     * A wrapper class used for the communication service.
+     */
+    private class VirtualDeviceId {
+        NetworkId networkId;
+        DeviceId deviceId;
+
+        public VirtualDeviceId(NetworkId networkId, DeviceId deviceId) {
+            this.networkId = networkId;
+            this.deviceId = deviceId;
+        }
+
+        public int hashCode() {
+            return Objects.hashCode(networkId, deviceId);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof VirtualDeviceId) {
+                final VirtualDeviceId that = (VirtualDeviceId) obj;
+                return this.getClass() == that.getClass() &&
+                        Objects.equal(this.networkId, that.networkId) &&
+                        Objects.equal(this.deviceId, that.deviceId);
+            }
+            return false;
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualFlowObjectiveStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualFlowObjectiveStore.java
new file mode 100644
index 0000000..5bcfabc
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualFlowObjectiveStore.java
@@ -0,0 +1,78 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.collect.Maps;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.Serializer;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+
+import java.util.concurrent.ConcurrentMap;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Distributed flow objective store for virtual network.
+ */
+@Component(immediate = true, enabled = false, service = VirtualNetworkFlowObjectiveStore.class)
+public class DistributedVirtualFlowObjectiveStore
+        extends SimpleVirtualFlowObjectiveStore
+        implements VirtualNetworkFlowObjectiveStore {
+
+    private final Logger log = getLogger(getClass());
+
+    private ConsistentMap<NetworkId, ConcurrentMap<Integer, byte[]>> nextGroupsMap;
+    private static final String VNET_FLOW_OBJ_GROUP_MAP_NAME =
+            "onos-networkId-flowobjective-groups";
+    private static final String VNET_FLOW_OBJ_GROUP_MAP_FRIENDLYNAME =
+            "DistributedVirtualFlowObjectiveStore";
+
+    @Override
+    protected void initNextGroupsMap() {
+        nextGroupsMap = storageService.<NetworkId, ConcurrentMap<Integer, byte[]>>consistentMapBuilder()
+                .withName(VNET_FLOW_OBJ_GROUP_MAP_NAME)
+                .withSerializer(Serializer.using(
+                        new KryoNamespace.Builder()
+                                .register(KryoNamespaces.API)
+                                .register(NetworkId.class)
+                                .build(VNET_FLOW_OBJ_GROUP_MAP_FRIENDLYNAME)))
+                .build();
+
+    }
+
+    @Override
+    protected ConcurrentMap<Integer, byte[]> getNextGroups(NetworkId networkId) {
+        nextGroupsMap.computeIfAbsent(networkId, n -> {
+            log.debug("getNextGroups - creating new ConcurrentMap");
+            return Maps.newConcurrentMap();
+        });
+
+        return nextGroupsMap.get(networkId).value();
+    }
+
+    @Override
+    protected void updateNextGroupsMap(NetworkId networkId, ConcurrentMap<Integer,
+            byte[]> nextGroups) {
+        nextGroupsMap.put(networkId, nextGroups);
+    }
+
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualFlowRuleStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualFlowRuleStore.java
new file mode 100644
index 0000000..8722c92
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualFlowRuleStore.java
@@ -0,0 +1,922 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.Futures;
+import org.onlab.util.KryoNamespace;
+import org.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.store.impl.primitives.VirtualDeviceId;
+import org.onosproject.incubator.net.virtual.store.impl.primitives.VirtualFlowEntry;
+import org.onosproject.incubator.net.virtual.store.impl.primitives.VirtualFlowRule;
+import org.onosproject.incubator.net.virtual.store.impl.primitives.VirtualFlowRuleBatchEvent;
+import org.onosproject.incubator.net.virtual.store.impl.primitives.VirtualFlowRuleBatchOperation;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.BatchOperationEntry;
+import org.onosproject.net.flow.CompletedBatchOperation;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowId;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.FlowRuleStoreDelegate;
+import org.onosproject.net.flow.StoredFlowEntry;
+import org.onosproject.net.flow.TableStatisticsEntry;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchEntry;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchEvent;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchRequest;
+import org.onosproject.store.Timestamp;
+import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
+import org.onosproject.store.cluster.messaging.ClusterMessage;
+import org.onosproject.store.cluster.messaging.ClusterMessageHandler;
+import org.onosproject.store.cluster.messaging.MessageSubject;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.EventuallyConsistentMapEvent;
+import org.onosproject.store.service.EventuallyConsistentMapListener;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.onlab.util.Tools.get;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.incubator.net.virtual.store.impl.OsgiPropertyConstants.*;
+import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Manages inventory of flow rules using a distributed state management protocol
+ * for virtual networks.
+ */
+//TODO: support backup and persistent mechanism
+@Component(immediate = true, enabled = false, service = VirtualNetworkFlowRuleStore.class,
+        property = {
+                MESSAGE_HANDLER_THREAD_POOL_SIZE + ":Integer=" + MESSAGE_HANDLER_THREAD_POOL_SIZE_DEFAULT,
+                BACKUP_PERIOD_MILLIS + ":Integer=" + BACKUP_PERIOD_MILLIS_DEFAULT,
+                PERSISTENCE_ENABLED + ":Boolean=" + PERSISTENCE_ENABLED_DEFAULT,
+        })
+
+public class DistributedVirtualFlowRuleStore
+        extends AbstractVirtualStore<FlowRuleBatchEvent, FlowRuleStoreDelegate>
+        implements VirtualNetworkFlowRuleStore {
+
+    private final Logger log = getLogger(getClass());
+
+    //TODO: confirm this working fine with multiple thread more than 1
+    private static final long FLOW_RULE_STORE_TIMEOUT_MILLIS = 5000;
+
+    private static final String FLOW_OP_TOPIC = "virtual-flow-ops-ids";
+
+    // MessageSubjects used by DistributedVirtualFlowRuleStore peer-peer communication.
+    private static final MessageSubject APPLY_BATCH_FLOWS
+            = new MessageSubject("virtual-peer-forward-apply-batch");
+    private static final MessageSubject GET_FLOW_ENTRY
+            = new MessageSubject("virtual-peer-forward-get-flow-entry");
+    private static final MessageSubject GET_DEVICE_FLOW_ENTRIES
+            = new MessageSubject("virtual-peer-forward-get-device-flow-entries");
+    private static final MessageSubject REMOVE_FLOW_ENTRY
+            = new MessageSubject("virtual-peer-forward-remove-flow-entry");
+    private static final MessageSubject REMOTE_APPLY_COMPLETED
+            = new MessageSubject("virtual-peer-apply-completed");
+
+    /** Number of threads in the message handler pool. */
+    private int msgHandlerThreadPoolSize = MESSAGE_HANDLER_THREAD_POOL_SIZE_DEFAULT;
+
+    /** Delay in ms between successive backup runs. */
+    private int backupPeriod = BACKUP_PERIOD_MILLIS_DEFAULT;
+
+    /** Indicates whether or not changes in the flow table should be persisted to disk.. */
+    private boolean persistenceEnabled = PERSISTENCE_ENABLED_DEFAULT;
+
+    private InternalFlowTable flowTable = new InternalFlowTable();
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ClusterCommunicationService clusterCommunicator;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ComponentConfigService configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected VirtualNetworkService vnaService;
+
+    private Map<Long, NodeId> pendingResponses = Maps.newConcurrentMap();
+    private ExecutorService messageHandlingExecutor;
+    private ExecutorService eventHandler;
+
+    private EventuallyConsistentMap<NetworkId, Map<DeviceId, List<TableStatisticsEntry>>> deviceTableStats;
+    private final EventuallyConsistentMapListener<NetworkId, Map<DeviceId, List<TableStatisticsEntry>>>
+            tableStatsListener = new InternalTableStatsListener();
+
+
+    protected final Serializer serializer = Serializer.using(KryoNamespace.newBuilder()
+                                                                     .register(KryoNamespaces.API)
+                                                                     .register(NetworkId.class)
+                                                                     .register(VirtualFlowRuleBatchOperation.class)
+                                                                     .register(VirtualFlowRuleBatchEvent.class)
+                                                                     .build());
+
+    protected final KryoNamespace.Builder serializerBuilder = KryoNamespace.newBuilder()
+            .register(KryoNamespaces.API)
+            .register(MastershipBasedTimestamp.class);
+
+    private IdGenerator idGenerator;
+    private NodeId local;
+
+
+    @Activate
+    public void activate(ComponentContext context) {
+        configService.registerProperties(getClass());
+
+        idGenerator = coreService.getIdGenerator(FLOW_OP_TOPIC);
+
+        local = clusterService.getLocalNode().id();
+
+        eventHandler = Executors.newSingleThreadExecutor(
+                groupedThreads("onos/virtual-flow", "event-handler", log));
+        messageHandlingExecutor = Executors.newFixedThreadPool(
+                msgHandlerThreadPoolSize, groupedThreads("onos/store/virtual-flow", "message-handlers", log));
+
+        registerMessageHandlers(messageHandlingExecutor);
+
+        deviceTableStats = storageService
+                .<NetworkId, Map<DeviceId, List<TableStatisticsEntry>>>eventuallyConsistentMapBuilder()
+                .withName("onos-virtual-flow-table-stats")
+                .withSerializer(serializerBuilder)
+                .withAntiEntropyPeriod(5, TimeUnit.SECONDS)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .withTombstonesDisabled()
+                .build();
+        deviceTableStats.addListener(tableStatsListener);
+
+        logConfig("Started");
+    }
+
+    @Deactivate
+    public void deactivate(ComponentContext context) {
+        configService.unregisterProperties(getClass(), false);
+        unregisterMessageHandlers();
+        deviceTableStats.removeListener(tableStatsListener);
+        deviceTableStats.destroy();
+        eventHandler.shutdownNow();
+        messageHandlingExecutor.shutdownNow();
+        log.info("Stopped");
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Modified
+    public void modified(ComponentContext context) {
+        if (context == null) {
+            logConfig("Default config");
+            return;
+        }
+
+        Dictionary properties = context.getProperties();
+        int newPoolSize;
+        int newBackupPeriod;
+        try {
+            String s = get(properties, MESSAGE_HANDLER_THREAD_POOL_SIZE);
+            newPoolSize = isNullOrEmpty(s) ? msgHandlerThreadPoolSize : Integer.parseInt(s.trim());
+
+            s = get(properties, BACKUP_PERIOD_MILLIS);
+            newBackupPeriod = isNullOrEmpty(s) ? backupPeriod : Integer.parseInt(s.trim());
+        } catch (NumberFormatException | ClassCastException e) {
+            newPoolSize = MESSAGE_HANDLER_THREAD_POOL_SIZE_DEFAULT;
+            newBackupPeriod = BACKUP_PERIOD_MILLIS_DEFAULT;
+        }
+
+        boolean restartBackupTask = false;
+
+        if (newBackupPeriod != backupPeriod) {
+            backupPeriod = newBackupPeriod;
+            restartBackupTask = true;
+        }
+        if (restartBackupTask) {
+            log.warn("Currently, backup tasks are not supported.");
+        }
+        if (newPoolSize != msgHandlerThreadPoolSize) {
+            msgHandlerThreadPoolSize = newPoolSize;
+            ExecutorService oldMsgHandler = messageHandlingExecutor;
+            messageHandlingExecutor = Executors.newFixedThreadPool(
+                    msgHandlerThreadPoolSize, groupedThreads("onos/store/virtual-flow", "message-handlers", log));
+
+            // replace previously registered handlers.
+            registerMessageHandlers(messageHandlingExecutor);
+            oldMsgHandler.shutdown();
+        }
+
+        logConfig("Reconfigured");
+    }
+
+    @Override
+    public int getFlowRuleCount(NetworkId networkId) {
+        AtomicInteger sum = new AtomicInteger(0);
+        DeviceService deviceService = vnaService.get(networkId, DeviceService.class);
+        deviceService.getDevices()
+                .forEach(device -> sum.addAndGet(
+                        Iterables.size(getFlowEntries(networkId, device.id()))));
+        return sum.get();
+    }
+
+    @Override
+    public FlowEntry getFlowEntry(NetworkId networkId, FlowRule rule) {
+        MastershipService mastershipService =
+                vnaService.get(networkId, MastershipService.class);
+        NodeId master = mastershipService.getMasterFor(rule.deviceId());
+
+        if (master == null) {
+            log.debug("Failed to getFlowEntry: No master for {}, vnet {}",
+                      rule.deviceId(), networkId);
+            return null;
+        }
+
+        if (Objects.equals(local, master)) {
+            return flowTable.getFlowEntry(networkId, rule);
+        }
+
+        log.trace("Forwarding getFlowEntry to {}, which is the primary (master) " +
+                          "for device {}, vnet {}",
+                  master, rule.deviceId(), networkId);
+
+        VirtualFlowRule vRule = new VirtualFlowRule(networkId, rule);
+
+        return Tools.futureGetOrElse(clusterCommunicator.sendAndReceive(vRule,
+                                                                        GET_FLOW_ENTRY,
+                                                                        serializer::encode,
+                                                                        serializer::decode,
+                                                                        master),
+                                     FLOW_RULE_STORE_TIMEOUT_MILLIS,
+                                     TimeUnit.MILLISECONDS,
+                                     null);
+    }
+
+    @Override
+    public Iterable<FlowEntry> getFlowEntries(NetworkId networkId, DeviceId deviceId) {
+        MastershipService mastershipService =
+                vnaService.get(networkId, MastershipService.class);
+        NodeId master = mastershipService.getMasterFor(deviceId);
+
+        if (master == null) {
+            log.debug("Failed to getFlowEntries: No master for {}, vnet {}", deviceId, networkId);
+            return Collections.emptyList();
+        }
+
+        if (Objects.equals(local, master)) {
+            return flowTable.getFlowEntries(networkId, deviceId);
+        }
+
+        log.trace("Forwarding getFlowEntries to {}, which is the primary (master) for device {}",
+                  master, deviceId);
+
+        return Tools.futureGetOrElse(
+                clusterCommunicator.sendAndReceive(deviceId,
+                                                   GET_DEVICE_FLOW_ENTRIES,
+                                                   serializer::encode,
+                                                   serializer::decode,
+                                                   master),
+                FLOW_RULE_STORE_TIMEOUT_MILLIS,
+                TimeUnit.MILLISECONDS,
+                Collections.emptyList());
+    }
+
+    @Override
+    public void storeBatch(NetworkId networkId, FlowRuleBatchOperation operation) {
+        if (operation.getOperations().isEmpty()) {
+            notifyDelegate(networkId, FlowRuleBatchEvent.completed(
+                    new FlowRuleBatchRequest(operation.id(), Collections.emptySet()),
+                    new CompletedBatchOperation(true, Collections.emptySet(), operation.deviceId())));
+            return;
+        }
+
+        DeviceId deviceId = operation.deviceId();
+        MastershipService mastershipService =
+                vnaService.get(networkId, MastershipService.class);
+        NodeId master = mastershipService.getMasterFor(deviceId);
+
+        if (master == null) {
+            log.warn("No master for {}, vnet {} : flows will be marked for removal", deviceId, networkId);
+
+            updateStoreInternal(networkId, operation);
+
+            notifyDelegate(networkId, FlowRuleBatchEvent.completed(
+                    new FlowRuleBatchRequest(operation.id(), Collections.emptySet()),
+                    new CompletedBatchOperation(true, Collections.emptySet(), operation.deviceId())));
+            return;
+        }
+
+        if (Objects.equals(local, master)) {
+            storeBatchInternal(networkId, operation);
+            return;
+        }
+
+        log.trace("Forwarding storeBatch to {}, which is the primary (master) for device {}, vent {}",
+                  master, deviceId, networkId);
+
+        clusterCommunicator.unicast(new VirtualFlowRuleBatchOperation(networkId, operation),
+                                    APPLY_BATCH_FLOWS,
+                                    serializer::encode,
+                                    master)
+                .whenComplete((result, error) -> {
+                    if (error != null) {
+                        log.warn("Failed to storeBatch: {} to {}", operation, master, error);
+
+                        Set<FlowRule> allFailures = operation.getOperations()
+                                .stream()
+                                .map(BatchOperationEntry::target)
+                                .collect(Collectors.toSet());
+
+                        notifyDelegate(networkId, FlowRuleBatchEvent.completed(
+                                new FlowRuleBatchRequest(operation.id(), Collections.emptySet()),
+                                new CompletedBatchOperation(false, allFailures, deviceId)));
+                    }
+                });
+    }
+
+    @Override
+    public void batchOperationComplete(NetworkId networkId, FlowRuleBatchEvent event) {
+        //FIXME: need a per device pending response
+        NodeId nodeId = pendingResponses.remove(event.subject().batchId());
+        if (nodeId == null) {
+            notifyDelegate(networkId, event);
+        } else {
+            // TODO check unicast return value
+            clusterCommunicator.unicast(new VirtualFlowRuleBatchEvent(networkId, event),
+                                        REMOTE_APPLY_COMPLETED, serializer::encode, nodeId);
+            //error log: log.warn("Failed to respond to peer for batch operation result");
+        }
+    }
+
+    @Override
+    public void deleteFlowRule(NetworkId networkId, FlowRule rule) {
+        storeBatch(networkId,
+                new FlowRuleBatchOperation(
+                        Collections.singletonList(
+                                new FlowRuleBatchEntry(
+                                        FlowRuleBatchEntry.FlowRuleOperation.REMOVE,
+                                        rule)), rule.deviceId(), idGenerator.getNewId()));
+    }
+
+    @Override
+    public FlowRuleEvent addOrUpdateFlowRule(NetworkId networkId, FlowEntry rule) {
+        MastershipService mastershipService =
+                vnaService.get(networkId, MastershipService.class);
+        NodeId master = mastershipService.getMasterFor(rule.deviceId());
+        if (Objects.equals(local, master)) {
+            return addOrUpdateFlowRuleInternal(networkId, rule);
+        }
+
+        log.warn("Tried to update FlowRule {} state,"
+                         + " while the Node was not the master.", rule);
+        return null;
+    }
+
+    private FlowRuleEvent addOrUpdateFlowRuleInternal(NetworkId networkId, FlowEntry rule) {
+        // check if this new rule is an update to an existing entry
+        StoredFlowEntry stored = flowTable.getFlowEntry(networkId, rule);
+        if (stored != null) {
+            //FIXME modification of "stored" flow entry outside of flow table
+            stored.setBytes(rule.bytes());
+            stored.setLife(rule.life(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
+            stored.setLiveType(rule.liveType());
+            stored.setPackets(rule.packets());
+            stored.setLastSeen();
+            if (stored.state() == FlowEntry.FlowEntryState.PENDING_ADD) {
+                stored.setState(FlowEntry.FlowEntryState.ADDED);
+                return new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED, rule);
+            }
+            return new FlowRuleEvent(FlowRuleEvent.Type.RULE_UPDATED, rule);
+        }
+
+        // TODO: Confirm if this behavior is correct. See SimpleFlowRuleStore
+        // TODO: also update backup if the behavior is correct.
+        flowTable.add(networkId, rule);
+        return null;
+    }
+
+    @Override
+    public FlowRuleEvent removeFlowRule(NetworkId networkId, FlowEntry rule) {
+        final DeviceId deviceId = rule.deviceId();
+
+        MastershipService mastershipService =
+                vnaService.get(networkId, MastershipService.class);
+        NodeId master = mastershipService.getMasterFor(deviceId);
+
+        if (Objects.equals(local, master)) {
+            // bypass and handle it locally
+            return removeFlowRuleInternal(new VirtualFlowEntry(networkId, rule));
+        }
+
+        if (master == null) {
+            log.warn("Failed to removeFlowRule: No master for {}", deviceId);
+            // TODO: revisit if this should be null (="no-op") or Exception
+            return null;
+        }
+
+        log.trace("Forwarding removeFlowRule to {}, which is the master for device {}",
+                  master, deviceId);
+
+        return Futures.getUnchecked(clusterCommunicator.sendAndReceive(
+                new VirtualFlowEntry(networkId, rule),
+                REMOVE_FLOW_ENTRY,
+                serializer::encode,
+                serializer::decode,
+                master));
+    }
+
+    @Override
+    public FlowRuleEvent pendingFlowRule(NetworkId networkId, FlowEntry rule) {
+        MastershipService mastershipService =
+                vnaService.get(networkId, MastershipService.class);
+        if (mastershipService.isLocalMaster(rule.deviceId())) {
+            StoredFlowEntry stored = flowTable.getFlowEntry(networkId, rule);
+            if (stored != null &&
+                    stored.state() != FlowEntry.FlowEntryState.PENDING_ADD) {
+                stored.setState(FlowEntry.FlowEntryState.PENDING_ADD);
+                return new FlowRuleEvent(FlowRuleEvent.Type.RULE_UPDATED, rule);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void purgeFlowRules(NetworkId networkId) {
+        flowTable.purgeFlowRules(networkId);
+    }
+
+    @Override
+    public FlowRuleEvent updateTableStatistics(NetworkId networkId,
+                                               DeviceId deviceId,
+                                               List<TableStatisticsEntry> tableStats) {
+        if (deviceTableStats.get(networkId) == null) {
+            deviceTableStats.put(networkId, Maps.newConcurrentMap());
+        }
+        deviceTableStats.get(networkId).put(deviceId, tableStats);
+        return null;
+    }
+
+    @Override
+    public Iterable<TableStatisticsEntry> getTableStatistics(NetworkId networkId, DeviceId deviceId) {
+        MastershipService mastershipService =
+                vnaService.get(networkId, MastershipService.class);
+        NodeId master = mastershipService.getMasterFor(deviceId);
+
+        if (master == null) {
+            log.debug("Failed to getTableStats: No master for {}", deviceId);
+            return Collections.emptyList();
+        }
+
+        if (deviceTableStats.get(networkId) == null) {
+            deviceTableStats.put(networkId, Maps.newConcurrentMap());
+        }
+
+        List<TableStatisticsEntry> tableStats = deviceTableStats.get(networkId).get(deviceId);
+        if (tableStats == null) {
+            return Collections.emptyList();
+        }
+        return ImmutableList.copyOf(tableStats);
+    }
+
+    private void registerMessageHandlers(ExecutorService executor) {
+        clusterCommunicator.addSubscriber(APPLY_BATCH_FLOWS, new OnStoreBatch(), executor);
+        clusterCommunicator.<VirtualFlowRuleBatchEvent>addSubscriber(
+                REMOTE_APPLY_COMPLETED, serializer::decode,
+                this::notifyDelicateByNetwork, executor);
+        clusterCommunicator.addSubscriber(
+                GET_FLOW_ENTRY, serializer::decode, this::getFlowEntryByNetwork,
+                serializer::encode, executor);
+        clusterCommunicator.addSubscriber(
+                GET_DEVICE_FLOW_ENTRIES, serializer::decode,
+                this::getFlowEntriesByNetwork,
+                serializer::encode, executor);
+        clusterCommunicator.addSubscriber(
+                REMOVE_FLOW_ENTRY, serializer::decode, this::removeFlowRuleInternal,
+                serializer::encode, executor);
+    }
+
+    private void unregisterMessageHandlers() {
+        clusterCommunicator.removeSubscriber(REMOVE_FLOW_ENTRY);
+        clusterCommunicator.removeSubscriber(GET_DEVICE_FLOW_ENTRIES);
+        clusterCommunicator.removeSubscriber(GET_FLOW_ENTRY);
+        clusterCommunicator.removeSubscriber(APPLY_BATCH_FLOWS);
+        clusterCommunicator.removeSubscriber(REMOTE_APPLY_COMPLETED);
+    }
+
+
+    private void logConfig(String prefix) {
+        log.info("{} with msgHandlerPoolSize = {}; backupPeriod = {}",
+                 prefix, msgHandlerThreadPoolSize, backupPeriod);
+    }
+
+    private void storeBatchInternal(NetworkId networkId, FlowRuleBatchOperation operation) {
+
+        final DeviceId did = operation.deviceId();
+        //final Collection<FlowEntry> ft = flowTable.getFlowEntries(did);
+        Set<FlowRuleBatchEntry> currentOps = updateStoreInternal(networkId, operation);
+        if (currentOps.isEmpty()) {
+            batchOperationComplete(networkId, FlowRuleBatchEvent.completed(
+                    new FlowRuleBatchRequest(operation.id(), Collections.emptySet()),
+                    new CompletedBatchOperation(true, Collections.emptySet(), did)));
+            return;
+        }
+
+        //Confirm that flowrule service is created
+        vnaService.get(networkId, FlowRuleService.class);
+
+        notifyDelegate(networkId, FlowRuleBatchEvent.requested(new
+                                                            FlowRuleBatchRequest(operation.id(),
+                                                                                 currentOps), operation.deviceId()));
+    }
+
+    private Set<FlowRuleBatchEntry> updateStoreInternal(NetworkId networkId,
+                                                        FlowRuleBatchOperation operation) {
+        return operation.getOperations().stream().map(
+                op -> {
+                    StoredFlowEntry entry;
+                    switch (op.operator()) {
+                        case ADD:
+                            entry = new DefaultFlowEntry(op.target());
+                            // always add requested FlowRule
+                            // Note: 2 equal FlowEntry may have different treatment
+                            flowTable.remove(networkId, entry.deviceId(), entry);
+                            flowTable.add(networkId, entry);
+
+                            return op;
+                        case REMOVE:
+                            entry = flowTable.getFlowEntry(networkId, op.target());
+                            if (entry != null) {
+                                //FIXME modification of "stored" flow entry outside of flow table
+                                entry.setState(FlowEntry.FlowEntryState.PENDING_REMOVE);
+                                log.debug("Setting state of rule to pending remove: {}", entry);
+                                return op;
+                            }
+                            break;
+                        case MODIFY:
+                            //TODO: figure this out at some point
+                            break;
+                        default:
+                            log.warn("Unknown flow operation operator: {}", op.operator());
+                    }
+                    return null;
+                }
+        ).filter(Objects::nonNull).collect(Collectors.toSet());
+    }
+
+    private FlowRuleEvent removeFlowRuleInternal(VirtualFlowEntry rule) {
+        final DeviceId deviceId = rule.flowEntry().deviceId();
+        // This is where one could mark a rule as removed and still keep it in the store.
+        final FlowEntry removed = flowTable.remove(rule.networkId(), deviceId, rule.flowEntry());
+        // rule may be partial rule that is missing treatment, we should use rule from store instead
+        return removed != null ? new FlowRuleEvent(RULE_REMOVED, removed) : null;
+    }
+
+    private final class OnStoreBatch implements ClusterMessageHandler {
+
+        @Override
+        public void handle(final ClusterMessage message) {
+            VirtualFlowRuleBatchOperation vOperation = serializer.decode(message.payload());
+            log.debug("received batch request {}", vOperation);
+
+            FlowRuleBatchOperation operation = vOperation.operation();
+
+            final DeviceId deviceId = operation.deviceId();
+            MastershipService mastershipService =
+                    vnaService.get(vOperation.networkId(), MastershipService.class);
+            NodeId master = mastershipService.getMasterFor(deviceId);
+            if (!Objects.equals(local, master)) {
+                Set<FlowRule> failures = new HashSet<>(operation.size());
+                for (FlowRuleBatchEntry op : operation.getOperations()) {
+                    failures.add(op.target());
+                }
+                CompletedBatchOperation allFailed = new CompletedBatchOperation(false, failures, deviceId);
+                // This node is no longer the master, respond as all failed.
+                // TODO: we might want to wrap response in envelope
+                // to distinguish sw programming failure and hand over
+                // it make sense in the latter case to retry immediately.
+                message.respond(serializer.encode(allFailed));
+                return;
+            }
+
+            pendingResponses.put(operation.id(), message.sender());
+            storeBatchInternal(vOperation.networkId(), operation);
+        }
+    }
+
+    /**
+     * Returns flow rule entry using virtual flow rule.
+     *
+     * @param rule an encapsulated flow rule to be queried
+     */
+    private FlowEntry getFlowEntryByNetwork(VirtualFlowRule rule) {
+        return flowTable.getFlowEntry(rule.networkId(), rule.rule());
+    }
+
+    /**
+     * returns flow entries using virtual device id.
+     *
+     * @param deviceId an encapsulated virtual device id
+     * @return a set of flow entries
+     */
+    private Set<FlowEntry> getFlowEntriesByNetwork(VirtualDeviceId deviceId) {
+        return flowTable.getFlowEntries(deviceId.networkId(), deviceId.deviceId());
+    }
+
+    /**
+     * span out Flow Rule Batch event according to virtual network id.
+     *
+     * @param event a event to be span out
+     */
+    private void notifyDelicateByNetwork(VirtualFlowRuleBatchEvent event) {
+        batchOperationComplete(event.networkId(), event.event());
+    }
+
+    private class InternalFlowTable {
+        //TODO replace the Map<V,V> with ExtendedSet
+        //TODO: support backup mechanism
+        private final Map<NetworkId, Map<DeviceId, Map<FlowId, Map<StoredFlowEntry, StoredFlowEntry>>>>
+                flowEntriesMap = Maps.newConcurrentMap();
+        private final Map<NetworkId, Map<DeviceId, Long>> lastUpdateTimesMap = Maps.newConcurrentMap();
+
+        private Map<DeviceId, Map<FlowId, Map<StoredFlowEntry, StoredFlowEntry>>>
+        getFlowEntriesByNetwork(NetworkId networkId) {
+            return flowEntriesMap.computeIfAbsent(networkId, k -> Maps.newConcurrentMap());
+        }
+
+        private Map<DeviceId, Long> getLastUpdateTimesByNetwork(NetworkId networkId) {
+            return lastUpdateTimesMap.computeIfAbsent(networkId, k -> Maps.newConcurrentMap());
+        }
+
+        /**
+         * Returns the flow table for specified device.
+         *
+         * @param networkId virtual network identifier
+         * @param deviceId identifier of the device
+         * @return Map representing Flow Table of given device.
+         */
+        private Map<FlowId, Map<StoredFlowEntry, StoredFlowEntry>>
+        getFlowTable(NetworkId networkId, DeviceId deviceId) {
+            Map<DeviceId, Map<FlowId, Map<StoredFlowEntry, StoredFlowEntry>>>
+                    flowEntries = getFlowEntriesByNetwork(networkId);
+            if (persistenceEnabled) {
+                //TODO: support persistent
+                log.warn("Persistent is not supported");
+                return null;
+            } else {
+                return flowEntries.computeIfAbsent(deviceId, id -> Maps.newConcurrentMap());
+            }
+        }
+
+        private Map<FlowId, Map<StoredFlowEntry, StoredFlowEntry>>
+        getFlowTableCopy(NetworkId networkId, DeviceId deviceId) {
+
+            Map<DeviceId, Map<FlowId, Map<StoredFlowEntry, StoredFlowEntry>>>
+                    flowEntries = getFlowEntriesByNetwork(networkId);
+            Map<FlowId, Map<StoredFlowEntry, StoredFlowEntry>> copy = Maps.newHashMap();
+
+            if (persistenceEnabled) {
+                //TODO: support persistent
+                log.warn("Persistent is not supported");
+                return null;
+            } else {
+                flowEntries.computeIfAbsent(deviceId, id -> Maps.newConcurrentMap()).forEach((k, v) -> {
+                    copy.put(k, Maps.newHashMap(v));
+                });
+                return copy;
+            }
+        }
+
+        private Map<StoredFlowEntry, StoredFlowEntry>
+        getFlowEntriesInternal(NetworkId networkId, DeviceId deviceId, FlowId flowId) {
+
+            return getFlowTable(networkId, deviceId)
+                    .computeIfAbsent(flowId, id -> Maps.newConcurrentMap());
+        }
+
+        private StoredFlowEntry getFlowEntryInternal(NetworkId networkId, FlowRule rule) {
+
+            return getFlowEntriesInternal(networkId, rule.deviceId(), rule.id()).get(rule);
+        }
+
+        private Set<FlowEntry> getFlowEntriesInternal(NetworkId networkId, DeviceId deviceId) {
+
+            return getFlowTable(networkId, deviceId).values().stream()
+                    .flatMap(m -> m.values().stream())
+                    .collect(Collectors.toSet());
+        }
+
+        public StoredFlowEntry getFlowEntry(NetworkId networkId, FlowRule rule) {
+            return getFlowEntryInternal(networkId, rule);
+        }
+
+        public Set<FlowEntry> getFlowEntries(NetworkId networkId, DeviceId deviceId) {
+
+            return getFlowEntriesInternal(networkId, deviceId);
+        }
+
+        public void add(NetworkId networkId, FlowEntry rule) {
+            Map<DeviceId, Long> lastUpdateTimes = getLastUpdateTimesByNetwork(networkId);
+
+            getFlowEntriesInternal(networkId, rule.deviceId(), rule.id())
+                    .compute((StoredFlowEntry) rule, (k, stored) -> {
+                        //TODO compare stored and rule timestamps
+                        //TODO the key is not updated
+                        return (StoredFlowEntry) rule;
+                    });
+            lastUpdateTimes.put(rule.deviceId(), System.currentTimeMillis());
+        }
+
+        public FlowEntry remove(NetworkId networkId, DeviceId deviceId, FlowEntry rule) {
+            final AtomicReference<FlowEntry> removedRule = new AtomicReference<>();
+            Map<DeviceId, Long> lastUpdateTimes = getLastUpdateTimesByNetwork(networkId);
+
+            getFlowEntriesInternal(networkId, rule.deviceId(), rule.id())
+                    .computeIfPresent((StoredFlowEntry) rule, (k, stored) -> {
+                        if (rule instanceof DefaultFlowEntry) {
+                            DefaultFlowEntry toRemove = (DefaultFlowEntry) rule;
+                            if (stored instanceof DefaultFlowEntry) {
+                                DefaultFlowEntry storedEntry = (DefaultFlowEntry) stored;
+                                if (toRemove.created() < storedEntry.created()) {
+                                    log.debug("Trying to remove more recent flow entry {} (stored: {})",
+                                              toRemove, stored);
+                                    // the key is not updated, removedRule remains null
+                                    return stored;
+                                }
+                            }
+                        }
+                        removedRule.set(stored);
+                        return null;
+                    });
+
+            if (removedRule.get() != null) {
+                lastUpdateTimes.put(deviceId, System.currentTimeMillis());
+                return removedRule.get();
+            } else {
+                return null;
+            }
+        }
+
+        public void purgeFlowRule(NetworkId networkId, DeviceId deviceId) {
+            Map<DeviceId, Map<FlowId, Map<StoredFlowEntry, StoredFlowEntry>>>
+                    flowEntries = getFlowEntriesByNetwork(networkId);
+            flowEntries.remove(deviceId);
+        }
+
+        public void purgeFlowRules(NetworkId networkId) {
+            Map<DeviceId, Map<FlowId, Map<StoredFlowEntry, StoredFlowEntry>>>
+                    flowEntries = getFlowEntriesByNetwork(networkId);
+            flowEntries.clear();
+        }
+    }
+
+    private class InternalTableStatsListener
+            implements EventuallyConsistentMapListener<NetworkId, Map<DeviceId, List<TableStatisticsEntry>>> {
+
+        @Override
+        public void event(EventuallyConsistentMapEvent<NetworkId, Map<DeviceId,
+                List<TableStatisticsEntry>>> event) {
+            //TODO: Generate an event to listeners (do we need?)
+        }
+    }
+
+    public final class MastershipBasedTimestamp implements Timestamp {
+
+        private final long termNumber;
+        private final long sequenceNumber;
+
+        /**
+         * Default constructor for serialization.
+         */
+        protected MastershipBasedTimestamp() {
+            this.termNumber = -1;
+            this.sequenceNumber = -1;
+        }
+
+        /**
+         * Default version tuple.
+         *
+         * @param termNumber the mastership termNumber
+         * @param sequenceNumber  the sequenceNumber number within the termNumber
+         */
+        public MastershipBasedTimestamp(long termNumber, long sequenceNumber) {
+            this.termNumber = termNumber;
+            this.sequenceNumber = sequenceNumber;
+        }
+
+        @Override
+        public int compareTo(Timestamp o) {
+            checkArgument(o instanceof MastershipBasedTimestamp,
+                          "Must be MastershipBasedTimestamp", o);
+            MastershipBasedTimestamp that = (MastershipBasedTimestamp) o;
+
+            return ComparisonChain.start()
+                    .compare(this.termNumber, that.termNumber)
+                    .compare(this.sequenceNumber, that.sequenceNumber)
+                    .result();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(termNumber, sequenceNumber);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (!(obj instanceof MastershipBasedTimestamp)) {
+                return false;
+            }
+            MastershipBasedTimestamp that = (MastershipBasedTimestamp) obj;
+            return Objects.equals(this.termNumber, that.termNumber) &&
+                    Objects.equals(this.sequenceNumber, that.sequenceNumber);
+        }
+
+        @Override
+        public String toString() {
+            return MoreObjects.toStringHelper(getClass())
+                    .add("termNumber", termNumber)
+                    .add("sequenceNumber", sequenceNumber)
+                    .toString();
+        }
+
+        /**
+         * Returns the termNumber.
+         *
+         * @return termNumber
+         */
+        public long termNumber() {
+            return termNumber;
+        }
+
+        /**
+         * Returns the sequenceNumber number.
+         *
+         * @return sequenceNumber
+         */
+        public long sequenceNumber() {
+            return sequenceNumber;
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualNetworkStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualNetworkStore.java
new file mode 100644
index 0000000..b756c62
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualNetworkStore.java
@@ -0,0 +1,954 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.virtual.store.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
+import org.onosproject.incubator.net.virtual.DefaultVirtualHost;
+import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
+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.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.Key;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.DistributedSet;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.SetEvent;
+import org.onosproject.store.service.SetEventListener;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.BiFunction;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of the virtual network store.
+ */
+@Component(immediate = true, service = VirtualNetworkStore.class)
+public class DistributedVirtualNetworkStore
+        extends AbstractStore<VirtualNetworkEvent, VirtualNetworkStoreDelegate>
+        implements VirtualNetworkStore {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected CoreService coreService;
+
+    private IdGenerator idGenerator;
+
+    // Track tenants by ID
+    private DistributedSet<TenantId> tenantIdSet;
+
+    // Listener for tenant events
+    private final SetEventListener<TenantId> setListener = new InternalSetListener();
+
+    // Track virtual networks by network Id
+    private ConsistentMap<NetworkId, VirtualNetwork> networkIdVirtualNetworkConsistentMap;
+    private Map<NetworkId, VirtualNetwork> networkIdVirtualNetworkMap;
+
+    // Listener for virtual network events
+    private final MapEventListener<NetworkId, VirtualNetwork> virtualNetworkMapListener =
+            new InternalMapListener<>((mapEventType, virtualNetwork) -> {
+                VirtualNetworkEvent.Type eventType =
+                    mapEventType.equals(MapEvent.Type.INSERT)
+                            ? VirtualNetworkEvent.Type.NETWORK_ADDED :
+                    mapEventType.equals(MapEvent.Type.UPDATE)
+                            ? VirtualNetworkEvent.Type.NETWORK_UPDATED :
+                    mapEventType.equals(MapEvent.Type.REMOVE)
+                            ? VirtualNetworkEvent.Type.NETWORK_REMOVED : null;
+                return eventType == null ? null : new VirtualNetworkEvent(eventType, virtualNetwork.id());
+            });
+
+    // Listener for virtual device events
+    private final MapEventListener<VirtualDeviceId, VirtualDevice> virtualDeviceMapListener =
+            new InternalMapListener<>((mapEventType, virtualDevice) -> {
+                VirtualNetworkEvent.Type eventType =
+                        mapEventType.equals(MapEvent.Type.INSERT)
+                                ? VirtualNetworkEvent.Type.VIRTUAL_DEVICE_ADDED :
+                        mapEventType.equals(MapEvent.Type.UPDATE)
+                                ? VirtualNetworkEvent.Type.VIRTUAL_DEVICE_UPDATED :
+                        mapEventType.equals(MapEvent.Type.REMOVE)
+                                ? VirtualNetworkEvent.Type.VIRTUAL_DEVICE_REMOVED : null;
+                return eventType == null ? null :
+                        new VirtualNetworkEvent(eventType, virtualDevice.networkId(), virtualDevice);
+            });
+
+    // Track virtual network IDs by tenant Id
+    private ConsistentMap<TenantId, Set<NetworkId>> tenantIdNetworkIdSetConsistentMap;
+    private Map<TenantId, Set<NetworkId>> tenantIdNetworkIdSetMap;
+
+    // Track virtual devices by device Id
+    private ConsistentMap<VirtualDeviceId, VirtualDevice> deviceIdVirtualDeviceConsistentMap;
+    private Map<VirtualDeviceId, VirtualDevice> deviceIdVirtualDeviceMap;
+
+    // Track device IDs by network Id
+    private ConsistentMap<NetworkId, Set<DeviceId>> networkIdDeviceIdSetConsistentMap;
+    private Map<NetworkId, Set<DeviceId>> networkIdDeviceIdSetMap;
+
+    // Track virtual hosts by host Id
+    private ConsistentMap<HostId, VirtualHost> hostIdVirtualHostConsistentMap;
+    private Map<HostId, VirtualHost> hostIdVirtualHostMap;
+
+    // Track host IDs by network Id
+    private ConsistentMap<NetworkId, Set<HostId>> networkIdHostIdSetConsistentMap;
+    private Map<NetworkId, Set<HostId>> networkIdHostIdSetMap;
+
+    // Track virtual links by network Id
+    private ConsistentMap<NetworkId, Set<VirtualLink>> networkIdVirtualLinkSetConsistentMap;
+    private Map<NetworkId, Set<VirtualLink>> networkIdVirtualLinkSetMap;
+
+    // Track virtual ports by network Id
+    private ConsistentMap<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetConsistentMap;
+    private Map<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetMap;
+
+    // Track intent ID to TunnelIds
+    private ConsistentMap<Key, Set<TunnelId>> intentKeyTunnelIdSetConsistentMap;
+    private Map<Key, Set<TunnelId>> intentKeyTunnelIdSetMap;
+
+    private static final Serializer SERIALIZER = Serializer
+            .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
+                           .register(TenantId.class)
+                           .register(NetworkId.class)
+                           .register(VirtualNetwork.class)
+                           .register(DefaultVirtualNetwork.class)
+                           .register(VirtualDevice.class)
+                           .register(VirtualDeviceId.class)
+                           .register(DefaultVirtualDevice.class)
+                           .register(VirtualHost.class)
+                           .register(DefaultVirtualHost.class)
+                           .register(VirtualLink.class)
+                           .register(DefaultVirtualLink.class)
+                           .register(VirtualPort.class)
+                           .register(DefaultVirtualPort.class)
+                           .register(Device.class)
+                           .register(TunnelId.class)
+                           .register(VirtualNetworkIntent.class)
+                           .register(WallClockTimestamp.class)
+                           .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID)
+                           .build());
+
+    /**
+     * Distributed network store service activate method.
+     */
+    @Activate
+    public void activate() {
+        idGenerator = coreService.getIdGenerator(VirtualNetworkService.VIRTUAL_NETWORK_TOPIC);
+
+        tenantIdSet = storageService.<TenantId>setBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-tenantId")
+                .withRelaxedReadConsistency()
+                .build()
+                .asDistributedSet();
+        tenantIdSet.addListener(setListener);
+
+        networkIdVirtualNetworkConsistentMap = storageService.<NetworkId, VirtualNetwork>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-networkId-virtualnetwork")
+                .withRelaxedReadConsistency()
+                .build();
+        networkIdVirtualNetworkConsistentMap.addListener(virtualNetworkMapListener);
+        networkIdVirtualNetworkMap = networkIdVirtualNetworkConsistentMap.asJavaMap();
+
+        tenantIdNetworkIdSetConsistentMap = storageService.<TenantId, Set<NetworkId>>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-tenantId-networkIds")
+                .withRelaxedReadConsistency()
+                .build();
+        tenantIdNetworkIdSetMap = tenantIdNetworkIdSetConsistentMap.asJavaMap();
+
+        deviceIdVirtualDeviceConsistentMap = storageService.<VirtualDeviceId, VirtualDevice>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-deviceId-virtualdevice")
+                .withRelaxedReadConsistency()
+                .build();
+        deviceIdVirtualDeviceConsistentMap.addListener(virtualDeviceMapListener);
+        deviceIdVirtualDeviceMap = deviceIdVirtualDeviceConsistentMap.asJavaMap();
+
+        networkIdDeviceIdSetConsistentMap = storageService.<NetworkId, Set<DeviceId>>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-networkId-deviceIds")
+                .withRelaxedReadConsistency()
+                .build();
+        networkIdDeviceIdSetMap = networkIdDeviceIdSetConsistentMap.asJavaMap();
+
+        hostIdVirtualHostConsistentMap = storageService.<HostId, VirtualHost>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-hostId-virtualhost")
+                .withRelaxedReadConsistency()
+                .build();
+        hostIdVirtualHostMap = hostIdVirtualHostConsistentMap.asJavaMap();
+
+        networkIdHostIdSetConsistentMap = storageService.<NetworkId, Set<HostId>>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-networkId-hostIds")
+                .withRelaxedReadConsistency()
+                .build();
+        networkIdHostIdSetMap = networkIdHostIdSetConsistentMap.asJavaMap();
+
+        networkIdVirtualLinkSetConsistentMap = storageService.<NetworkId, Set<VirtualLink>>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-networkId-virtuallinks")
+                .withRelaxedReadConsistency()
+                .build();
+        networkIdVirtualLinkSetMap = networkIdVirtualLinkSetConsistentMap.asJavaMap();
+
+        networkIdVirtualPortSetConsistentMap = storageService.<NetworkId, Set<VirtualPort>>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-networkId-virtualports")
+                .withRelaxedReadConsistency()
+                .build();
+        networkIdVirtualPortSetMap = networkIdVirtualPortSetConsistentMap.asJavaMap();
+
+        intentKeyTunnelIdSetConsistentMap = storageService.<Key, Set<TunnelId>>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-intentKey-tunnelIds")
+                .withRelaxedReadConsistency()
+                .build();
+        intentKeyTunnelIdSetMap = intentKeyTunnelIdSetConsistentMap.asJavaMap();
+
+        log.info("Started");
+    }
+
+    /**
+     * Distributed network store service deactivate method.
+     */
+    @Deactivate
+    public void deactivate() {
+        tenantIdSet.removeListener(setListener);
+        networkIdVirtualNetworkConsistentMap.removeListener(virtualNetworkMapListener);
+        deviceIdVirtualDeviceConsistentMap.removeListener(virtualDeviceMapListener);
+        log.info("Stopped");
+    }
+
+    @Override
+    public void addTenantId(TenantId tenantId) {
+        tenantIdSet.add(tenantId);
+    }
+
+    @Override
+    public void removeTenantId(TenantId tenantId) {
+        //Remove all the virtual networks of this tenant
+        Set<VirtualNetwork> networkIdSet = getNetworks(tenantId);
+        if (networkIdSet != null) {
+            networkIdSet.forEach(virtualNetwork -> removeNetwork(virtualNetwork.id()));
+        }
+
+        tenantIdSet.remove(tenantId);
+    }
+
+    @Override
+    public Set<TenantId> getTenantIds() {
+        return ImmutableSet.copyOf(tenantIdSet);
+    }
+
+    @Override
+    public VirtualNetwork addNetwork(TenantId tenantId) {
+
+        checkState(tenantIdSet.contains(tenantId), "The tenant has not been registered. " + tenantId.id());
+        VirtualNetwork virtualNetwork = new DefaultVirtualNetwork(genNetworkId(), tenantId);
+        //TODO update both maps in one transaction.
+        networkIdVirtualNetworkMap.put(virtualNetwork.id(), virtualNetwork);
+
+        Set<NetworkId> networkIdSet = tenantIdNetworkIdSetMap.get(tenantId);
+        if (networkIdSet == null) {
+            networkIdSet = new HashSet<>();
+        }
+        networkIdSet.add(virtualNetwork.id());
+        tenantIdNetworkIdSetMap.put(tenantId, networkIdSet);
+
+        return virtualNetwork;
+    }
+
+    /**
+     * Returns a new network identifier from a virtual network block of identifiers.
+     *
+     * @return NetworkId network identifier
+     */
+    private NetworkId genNetworkId() {
+        NetworkId networkId;
+        do {
+            networkId = NetworkId.networkId(idGenerator.getNewId());
+        } while (!networkId.isVirtualNetworkId());
+
+        return networkId;
+    }
+
+    @Override
+    public void removeNetwork(NetworkId networkId) {
+        // Make sure that the virtual network exists before attempting to remove it.
+        checkState(networkExists(networkId), "The network does not exist.");
+
+        //Remove all the devices of this network
+        Set<VirtualDevice> deviceSet = getDevices(networkId);
+        if (deviceSet != null) {
+            deviceSet.forEach(virtualDevice -> removeDevice(networkId, virtualDevice.id()));
+        }
+        //TODO update both maps in one transaction.
+
+        VirtualNetwork virtualNetwork = networkIdVirtualNetworkMap.remove(networkId);
+        if (virtualNetwork == null) {
+            return;
+        }
+        TenantId tenantId = virtualNetwork.tenantId();
+
+        Set<NetworkId> networkIdSet = new HashSet<>();
+        tenantIdNetworkIdSetMap.get(tenantId).forEach(networkId1 -> {
+            if (networkId1.id().equals(networkId.id())) {
+                networkIdSet.add(networkId1);
+            }
+        });
+
+        tenantIdNetworkIdSetMap.compute(virtualNetwork.tenantId(), (id, existingNetworkIds) -> {
+            if (existingNetworkIds == null || existingNetworkIds.isEmpty()) {
+                return new HashSet<>();
+            } else {
+                return new HashSet<>(Sets.difference(existingNetworkIds, networkIdSet));
+            }
+        });
+    }
+
+    /**
+     * Returns if the network identifier exists.
+     *
+     * @param networkId network identifier
+     * @return true if the network identifier exists, false otherwise.
+     */
+    private boolean networkExists(NetworkId networkId) {
+        checkNotNull(networkId, "The network identifier cannot be null.");
+        return (networkIdVirtualNetworkMap.containsKey(networkId));
+    }
+
+    @Override
+    public VirtualDevice addDevice(NetworkId networkId, DeviceId deviceId) {
+        checkState(networkExists(networkId), "The network has not been added.");
+
+        Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
+        if (deviceIdSet == null) {
+            deviceIdSet = new HashSet<>();
+        }
+
+        checkState(!deviceIdSet.contains(deviceId), "The device already exists.");
+
+        VirtualDevice virtualDevice = new DefaultVirtualDevice(networkId, deviceId);
+        //TODO update both maps in one transaction.
+        deviceIdVirtualDeviceMap.put(new VirtualDeviceId(networkId, deviceId), virtualDevice);
+        deviceIdSet.add(deviceId);
+        networkIdDeviceIdSetMap.put(networkId, deviceIdSet);
+        return virtualDevice;
+    }
+
+    @Override
+    public void removeDevice(NetworkId networkId, DeviceId deviceId) {
+        checkState(networkExists(networkId), "The network has not been added.");
+        //Remove all the virtual ports of the this device
+        Set<VirtualPort> virtualPorts = getPorts(networkId, deviceId);
+        if (virtualPorts != null) {
+            virtualPorts.forEach(virtualPort -> removePort(networkId, deviceId, virtualPort.number()));
+        }
+        //TODO update both maps in one transaction.
+
+        Set<DeviceId> deviceIdSet = new HashSet<>();
+        networkIdDeviceIdSetMap.get(networkId).forEach(deviceId1 -> {
+            if (deviceId1.equals(deviceId)) {
+                deviceIdSet.add(deviceId1);
+            }
+        });
+
+        if (!deviceIdSet.isEmpty()) {
+            networkIdDeviceIdSetMap.compute(networkId, (id, existingDeviceIds) -> {
+                if (existingDeviceIds == null || existingDeviceIds.isEmpty()) {
+                    return new HashSet<>();
+                } else {
+                    return new HashSet<>(Sets.difference(existingDeviceIds, deviceIdSet));
+                }
+            });
+
+            deviceIdVirtualDeviceMap.remove(new VirtualDeviceId(networkId, deviceId));
+        }
+    }
+
+    @Override
+    public VirtualHost addHost(NetworkId networkId, HostId hostId, MacAddress mac,
+                               VlanId vlan, HostLocation location, Set<IpAddress> ips) {
+        checkState(networkExists(networkId), "The network has not been added.");
+        checkState(virtualPortExists(networkId, location.deviceId(), location.port()),
+                "The virtual port has not been created.");
+        Set<HostId> hostIdSet = networkIdHostIdSetMap.get(networkId);
+        if (hostIdSet == null) {
+            hostIdSet = new HashSet<>();
+        }
+        VirtualHost virtualhost = new DefaultVirtualHost(networkId, hostId, mac, vlan, location, ips);
+        //TODO update both maps in one transaction.
+        hostIdVirtualHostMap.put(hostId, virtualhost);
+        hostIdSet.add(hostId);
+        networkIdHostIdSetMap.put(networkId, hostIdSet);
+        return virtualhost;
+    }
+
+    @Override
+    public void removeHost(NetworkId networkId, HostId hostId) {
+        checkState(networkExists(networkId), "The network has not been added.");
+        //TODO update both maps in one transaction.
+
+        Set<HostId> hostIdSet = new HashSet<>();
+        networkIdHostIdSetMap.get(networkId).forEach(hostId1 -> {
+            if (hostId1.equals(hostId)) {
+                hostIdSet.add(hostId1);
+            }
+        });
+
+        networkIdHostIdSetMap.compute(networkId, (id, existingHostIds) -> {
+            if (existingHostIds == null || existingHostIds.isEmpty()) {
+                return new HashSet<>();
+            } else {
+                return new HashSet<>(Sets.difference(existingHostIds, hostIdSet));
+            }
+        });
+
+        hostIdVirtualHostMap.remove(hostId);
+    }
+
+    /**
+     * Returns if the given virtual port exists.
+     *
+     * @param networkId network identifier
+     * @param deviceId virtual device Id
+     * @param portNumber virtual port number
+     * @return true if the virtual port exists, false otherwise.
+     */
+    private boolean virtualPortExists(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
+        Set<VirtualPort> virtualPortSet = networkIdVirtualPortSetMap.get(networkId);
+        if (virtualPortSet != null) {
+            return virtualPortSet.stream().anyMatch(
+                    p -> p.element().id().equals(deviceId) &&
+                            p.number().equals(portNumber));
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public VirtualLink addLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst,
+                               Link.State state, TunnelId realizedBy) {
+        checkState(networkExists(networkId), "The network has not been added.");
+        checkState(virtualPortExists(networkId, src.deviceId(), src.port()),
+                "The source virtual port has not been added.");
+        checkState(virtualPortExists(networkId, dst.deviceId(), dst.port()),
+                "The destination virtual port has not been added.");
+        Set<VirtualLink> virtualLinkSet = networkIdVirtualLinkSetMap.get(networkId);
+        if (virtualLinkSet == null) {
+            virtualLinkSet = new HashSet<>();
+        }
+
+        // validate that the link does not already exist in this network
+        checkState(getLink(networkId, src, dst) == null,
+                "The virtual link already exists");
+        checkState(getLink(networkId, src, null) == null,
+                "The source connection point has been used by another link");
+        checkState(getLink(networkId, null, dst) == null,
+                "The destination connection point has been used by another link");
+
+        VirtualLink virtualLink = DefaultVirtualLink.builder()
+                .networkId(networkId)
+                .src(src)
+                .dst(dst)
+                .state(state)
+                .tunnelId(realizedBy)
+                .build();
+
+        virtualLinkSet.add(virtualLink);
+        networkIdVirtualLinkSetMap.put(networkId, virtualLinkSet);
+        return virtualLink;
+    }
+
+    @Override
+    public void updateLink(VirtualLink virtualLink, TunnelId tunnelId, Link.State state) {
+        checkState(networkExists(virtualLink.networkId()), "The network has not been added.");
+        Set<VirtualLink> virtualLinkSet = networkIdVirtualLinkSetMap.get(virtualLink.networkId());
+        if (virtualLinkSet == null) {
+            virtualLinkSet = new HashSet<>();
+            networkIdVirtualLinkSetMap.put(virtualLink.networkId(), virtualLinkSet);
+            log.warn("The updated virtual link {} has not been added", virtualLink);
+            return;
+        }
+        if (!virtualLinkSet.remove(virtualLink)) {
+            log.warn("The updated virtual link {} does not exist", virtualLink);
+            return;
+        }
+
+        VirtualLink newVirtualLink = DefaultVirtualLink.builder()
+                .networkId(virtualLink.networkId())
+                .src(virtualLink.src())
+                .dst(virtualLink.dst())
+                .tunnelId(tunnelId)
+                .state(state)
+                .build();
+
+        virtualLinkSet.add(newVirtualLink);
+        networkIdVirtualLinkSetMap.put(newVirtualLink.networkId(), virtualLinkSet);
+    }
+
+    @Override
+    public VirtualLink removeLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
+        checkState(networkExists(networkId), "The network has not been added.");
+
+        final VirtualLink virtualLink = getLink(networkId, src, dst);
+        if (virtualLink == null) {
+            log.warn("The removed virtual link between {} and {} does not exist", src, dst);
+            return null;
+        }
+        Set<VirtualLink> virtualLinkSet = new HashSet<>();
+        virtualLinkSet.add(virtualLink);
+
+        networkIdVirtualLinkSetMap.compute(networkId, (id, existingVirtualLinks) -> {
+            if (existingVirtualLinks == null || existingVirtualLinks.isEmpty()) {
+                return new HashSet<>();
+            } else {
+                return new HashSet<>(Sets.difference(existingVirtualLinks, virtualLinkSet));
+            }
+        });
+        return virtualLink;
+    }
+
+    @Override
+    public VirtualPort addPort(NetworkId networkId, DeviceId deviceId,
+                               PortNumber portNumber, ConnectPoint realizedBy) {
+        checkState(networkExists(networkId), "The network has not been added.");
+        Set<VirtualPort> virtualPortSet = networkIdVirtualPortSetMap.get(networkId);
+
+        if (virtualPortSet == null) {
+            virtualPortSet = new HashSet<>();
+        }
+
+        VirtualDevice device = deviceIdVirtualDeviceMap.get(new VirtualDeviceId(networkId, deviceId));
+        checkNotNull(device, "The device has not been created for deviceId: " + deviceId);
+
+        checkState(!virtualPortExists(networkId, deviceId, portNumber),
+                "The requested Port Number has been added.");
+
+        VirtualPort virtualPort = new DefaultVirtualPort(networkId, device,
+                                                         portNumber, realizedBy);
+        virtualPortSet.add(virtualPort);
+        networkIdVirtualPortSetMap.put(networkId, virtualPortSet);
+        notifyDelegate(new VirtualNetworkEvent(VirtualNetworkEvent.Type.VIRTUAL_PORT_ADDED,
+                                               networkId, device, virtualPort));
+        return virtualPort;
+    }
+
+    @Override
+    public void bindPort(NetworkId networkId, DeviceId deviceId,
+                         PortNumber portNumber, ConnectPoint realizedBy) {
+
+        Set<VirtualPort> virtualPortSet = networkIdVirtualPortSetMap
+                .get(networkId);
+
+        Optional<VirtualPort> virtualPortOptional = virtualPortSet.stream().filter(
+                p -> p.element().id().equals(deviceId) &&
+                        p.number().equals(portNumber)).findFirst();
+        checkState(virtualPortOptional.isPresent(), "The virtual port has not been added.");
+
+        VirtualDevice device = deviceIdVirtualDeviceMap.get(new VirtualDeviceId(networkId, deviceId));
+        checkNotNull(device, "The device has not been created for deviceId: "
+                + deviceId);
+
+        VirtualPort vPort = virtualPortOptional.get();
+        virtualPortSet.remove(vPort);
+        vPort = new DefaultVirtualPort(networkId, device, portNumber, realizedBy);
+        virtualPortSet.add(vPort);
+        networkIdVirtualPortSetMap.put(networkId, virtualPortSet);
+        notifyDelegate(new VirtualNetworkEvent(VirtualNetworkEvent.Type.VIRTUAL_PORT_UPDATED,
+                                               networkId, device, vPort));
+    }
+
+    @Override
+    public void updatePortState(NetworkId networkId, DeviceId deviceId,
+                                PortNumber portNumber, boolean isEnabled) {
+        checkState(networkExists(networkId), "No network with NetworkId %s exists.", networkId);
+
+        VirtualDevice device = deviceIdVirtualDeviceMap.get(new VirtualDeviceId(networkId, deviceId));
+        checkNotNull(device, "No device %s exists in NetworkId: %s", deviceId, networkId);
+
+        Set<VirtualPort> virtualPortSet = networkIdVirtualPortSetMap.get(networkId);
+        checkNotNull(virtualPortSet, "No port has been created for NetworkId: %s", networkId);
+
+        Optional<VirtualPort> virtualPortOptional = virtualPortSet.stream().filter(
+                p -> p.element().id().equals(deviceId) &&
+                        p.number().equals(portNumber)).findFirst();
+        checkState(virtualPortOptional.isPresent(), "The virtual port has not been added.");
+
+        VirtualPort oldPort = virtualPortOptional.get();
+        if (oldPort.isEnabled() == isEnabled) {
+            log.debug("No change in port state - port not updated");
+            return;
+        }
+        VirtualPort newPort = new DefaultVirtualPort(networkId, device, portNumber, isEnabled,
+                oldPort.realizedBy());
+        virtualPortSet.remove(oldPort);
+        virtualPortSet.add(newPort);
+        networkIdVirtualPortSetMap.put(networkId, virtualPortSet);
+        notifyDelegate(new VirtualNetworkEvent(VirtualNetworkEvent.Type.VIRTUAL_PORT_UPDATED,
+                                               networkId, device, newPort));
+        log.debug("port state changed from {} to {}", oldPort.isEnabled(), isEnabled);
+    }
+
+    @Override
+    public void removePort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
+        checkState(networkExists(networkId), "The network has not been added.");
+        VirtualDevice device = deviceIdVirtualDeviceMap.get(new VirtualDeviceId(networkId, deviceId));
+        checkNotNull(device, "The device has not been created for deviceId: "
+                + deviceId);
+
+        if (networkIdVirtualPortSetMap.get(networkId) == null) {
+            log.warn("No port has been created for NetworkId: {}", networkId);
+            return;
+        }
+
+        Set<VirtualPort> virtualPortSet = new HashSet<>();
+        networkIdVirtualPortSetMap.get(networkId).forEach(port -> {
+            if (port.element().id().equals(deviceId) && port.number().equals(portNumber)) {
+                virtualPortSet.add(port);
+            }
+        });
+
+        if (!virtualPortSet.isEmpty()) {
+            AtomicBoolean portRemoved = new AtomicBoolean(false);
+            networkIdVirtualPortSetMap.compute(networkId, (id, existingVirtualPorts) -> {
+                if (existingVirtualPorts == null || existingVirtualPorts.isEmpty()) {
+                    return new HashSet<>();
+                } else {
+                    portRemoved.set(true);
+                    return new HashSet<>(Sets.difference(existingVirtualPorts, virtualPortSet));
+                }
+            });
+            if (portRemoved.get()) {
+                virtualPortSet.forEach(virtualPort -> notifyDelegate(
+                        new VirtualNetworkEvent(VirtualNetworkEvent.Type.VIRTUAL_PORT_REMOVED,
+                                                networkId, device, virtualPort)
+                ));
+
+                //Remove all the virtual links connected to this virtual port
+                Set<VirtualLink> existingVirtualLinks = networkIdVirtualLinkSetMap.get(networkId);
+                if (existingVirtualLinks != null && !existingVirtualLinks.isEmpty()) {
+                    Set<VirtualLink> virtualLinkSet = new HashSet<>();
+                    ConnectPoint cp = new ConnectPoint(deviceId, portNumber);
+                    existingVirtualLinks.forEach(virtualLink -> {
+                        if (virtualLink.src().equals(cp) || virtualLink.dst().equals(cp)) {
+                            virtualLinkSet.add(virtualLink);
+                        }
+                    });
+                    virtualLinkSet.forEach(virtualLink ->
+                            removeLink(networkId, virtualLink.src(), virtualLink.dst()));
+                }
+
+                //Remove all the hosts connected to this virtual port
+                Set<HostId> hostIdSet = new HashSet<>();
+                hostIdVirtualHostMap.forEach((hostId, virtualHost) -> {
+                    if (virtualHost.location().deviceId().equals(deviceId) &&
+                            virtualHost.location().port().equals(portNumber)) {
+                        hostIdSet.add(hostId);
+                    }
+                });
+                hostIdSet.forEach(hostId -> removeHost(networkId, hostId));
+            }
+        }
+    }
+
+    @Override
+    public Set<VirtualNetwork> getNetworks(TenantId tenantId) {
+        Set<NetworkId> networkIdSet = tenantIdNetworkIdSetMap.get(tenantId);
+        Set<VirtualNetwork> virtualNetworkSet = new HashSet<>();
+        if (networkIdSet != null) {
+            networkIdSet.forEach(networkId -> {
+                if (networkIdVirtualNetworkMap.get(networkId) != null) {
+                    virtualNetworkSet.add(networkIdVirtualNetworkMap.get(networkId));
+                }
+            });
+        }
+        return ImmutableSet.copyOf(virtualNetworkSet);
+    }
+
+    @Override
+    public VirtualNetwork getNetwork(NetworkId networkId) {
+        return networkIdVirtualNetworkMap.get(networkId);
+    }
+
+    @Override
+    public Set<VirtualDevice> getDevices(NetworkId networkId) {
+        checkState(networkExists(networkId), "The network has not been added.");
+        Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
+        Set<VirtualDevice> virtualDeviceSet = new HashSet<>();
+        if (deviceIdSet != null) {
+            deviceIdSet.forEach(deviceId -> virtualDeviceSet.add(
+                    deviceIdVirtualDeviceMap.get(new VirtualDeviceId(networkId, deviceId))));
+        }
+        return ImmutableSet.copyOf(virtualDeviceSet);
+    }
+
+    @Override
+    public Set<VirtualHost> getHosts(NetworkId networkId) {
+        checkState(networkExists(networkId), "The network has not been added.");
+        Set<HostId> hostIdSet = networkIdHostIdSetMap.get(networkId);
+        Set<VirtualHost> virtualHostSet = new HashSet<>();
+        if (hostIdSet != null) {
+            hostIdSet.forEach(hostId -> virtualHostSet.add(hostIdVirtualHostMap.get(hostId)));
+        }
+        return ImmutableSet.copyOf(virtualHostSet);
+    }
+
+    @Override
+    public Set<VirtualLink> getLinks(NetworkId networkId) {
+        checkState(networkExists(networkId), "The network has not been added.");
+        Set<VirtualLink> virtualLinkSet = networkIdVirtualLinkSetMap.get(networkId);
+        if (virtualLinkSet == null) {
+            virtualLinkSet = new HashSet<>();
+        }
+        return ImmutableSet.copyOf(virtualLinkSet);
+    }
+
+    @Override
+    public VirtualLink getLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
+        Set<VirtualLink> virtualLinkSet = networkIdVirtualLinkSetMap.get(networkId);
+        if (virtualLinkSet == null) {
+            return null;
+        }
+
+        VirtualLink virtualLink = null;
+        for (VirtualLink link : virtualLinkSet) {
+            if (src == null && link.dst().equals(dst)) {
+                virtualLink = link;
+                break;
+            } else if (dst == null && link.src().equals(src)) {
+                virtualLink = link;
+                break;
+            } else if (link.src().equals(src) && link.dst().equals(dst)) {
+                virtualLink = link;
+                break;
+            }
+        }
+        return virtualLink;
+    }
+
+    @Override
+    public Set<VirtualPort> getPorts(NetworkId networkId, DeviceId deviceId) {
+        checkState(networkExists(networkId), "The network has not been added.");
+        Set<VirtualPort> virtualPortSet = networkIdVirtualPortSetMap.get(networkId);
+        if (virtualPortSet == null) {
+            virtualPortSet = new HashSet<>();
+        }
+
+        if (deviceId == null) {
+            return ImmutableSet.copyOf(virtualPortSet);
+        }
+
+        Set<VirtualPort> portSet = new HashSet<>();
+        virtualPortSet.forEach(virtualPort -> {
+            if (virtualPort.element().id().equals(deviceId)) {
+                portSet.add(virtualPort);
+            }
+        });
+        return ImmutableSet.copyOf(portSet);
+    }
+
+    @Override
+    public void addTunnelId(Intent intent, TunnelId tunnelId) {
+        // Add the tunnelId to the intent key set map
+        Set<TunnelId> tunnelIdSet = intentKeyTunnelIdSetMap.remove(intent.key());
+        if (tunnelIdSet == null) {
+            tunnelIdSet = new HashSet<>();
+        }
+        tunnelIdSet.add(tunnelId);
+        intentKeyTunnelIdSetMap.put(intent.key(), tunnelIdSet);
+    }
+
+    @Override
+    public Set<TunnelId> getTunnelIds(Intent intent) {
+        Set<TunnelId> tunnelIdSet = intentKeyTunnelIdSetMap.get(intent.key());
+        return tunnelIdSet == null ? new HashSet<TunnelId>() : ImmutableSet.copyOf(tunnelIdSet);
+    }
+
+    @Override
+    public void removeTunnelId(Intent intent, TunnelId tunnelId) {
+        Set<TunnelId> tunnelIdSet = new HashSet<>();
+        intentKeyTunnelIdSetMap.get(intent.key()).forEach(tunnelId1 -> {
+            if (tunnelId1.equals(tunnelId)) {
+                tunnelIdSet.add(tunnelId);
+            }
+        });
+
+        if (!tunnelIdSet.isEmpty()) {
+            intentKeyTunnelIdSetMap.compute(intent.key(), (key, existingTunnelIds) -> {
+                if (existingTunnelIds == null || existingTunnelIds.isEmpty()) {
+                    return new HashSet<>();
+                } else {
+                    return new HashSet<>(Sets.difference(existingTunnelIds, tunnelIdSet));
+                }
+            });
+        }
+    }
+
+    /**
+     * Listener class to map listener set events to the virtual network events.
+     */
+    private class InternalSetListener implements SetEventListener<TenantId> {
+        @Override
+        public void event(SetEvent<TenantId> event) {
+            VirtualNetworkEvent.Type type = null;
+            switch (event.type()) {
+                case ADD:
+                    type = VirtualNetworkEvent.Type.TENANT_REGISTERED;
+                    break;
+                case REMOVE:
+                    type = VirtualNetworkEvent.Type.TENANT_UNREGISTERED;
+                    break;
+                default:
+                    log.error("Unsupported event type: " + event.type());
+            }
+            notifyDelegate(new VirtualNetworkEvent(type, null));
+        }
+    }
+
+    /**
+     * Listener class to map listener map events to the virtual network events.
+     */
+    private class InternalMapListener<K, V> implements MapEventListener<K, V> {
+
+        private final BiFunction<MapEvent.Type, V, VirtualNetworkEvent> createEvent;
+
+        InternalMapListener(BiFunction<MapEvent.Type, V, VirtualNetworkEvent> createEvent) {
+            this.createEvent = createEvent;
+        }
+
+        @Override
+        public void event(MapEvent<K, V> event) {
+            checkNotNull(event.key());
+            VirtualNetworkEvent vnetEvent = null;
+            switch (event.type()) {
+                case INSERT:
+                    vnetEvent = createEvent.apply(event.type(), event.newValue().value());
+                    break;
+                case UPDATE:
+                    if ((event.oldValue().value() != null) && (event.newValue().value() == null)) {
+                        vnetEvent = createEvent.apply(MapEvent.Type.REMOVE, event.oldValue().value());
+                    } else {
+                        vnetEvent = createEvent.apply(event.type(), event.newValue().value());
+                    }
+                    break;
+                case REMOVE:
+                    if (event.oldValue() != null) {
+                        vnetEvent = createEvent.apply(event.type(), event.oldValue().value());
+                    }
+                    break;
+                default:
+                    log.error("Unsupported event type: " + event.type());
+            }
+            if (vnetEvent != null) {
+                notifyDelegate(vnetEvent);
+            }
+        }
+    }
+
+    /**
+     * A wrapper class to isolate device id from other virtual networks.
+     */
+
+    private static class VirtualDeviceId {
+
+        NetworkId networkId;
+        DeviceId deviceId;
+
+        public VirtualDeviceId(NetworkId networkId, DeviceId deviceId) {
+            this.networkId = networkId;
+            this.deviceId = deviceId;
+        }
+
+        public NetworkId getNetworkId() {
+            return networkId;
+        }
+
+        public DeviceId getDeviceId() {
+            return deviceId;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(networkId, deviceId);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+
+            if (obj instanceof VirtualDeviceId) {
+                VirtualDeviceId that = (VirtualDeviceId) obj;
+                return this.deviceId.equals(that.deviceId) &&
+                        this.networkId.equals(that.networkId);
+            }
+            return false;
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualPacketStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualPacketStore.java
new file mode 100644
index 0000000..16636a5
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/DistributedVirtualPacketStore.java
@@ -0,0 +1,413 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkPacketStore;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketEvent;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketRequest;
+import org.onosproject.net.packet.PacketStoreDelegate;
+import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
+import org.onosproject.store.cluster.messaging.MessageSubject;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.util.concurrent.Executors.newFixedThreadPool;
+import static org.onlab.util.Tools.get;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.incubator.net.virtual.store.impl.OsgiPropertyConstants.MESSAGE_HANDLER_THREAD_POOL_SIZE;
+import static org.onosproject.incubator.net.virtual.store.impl.OsgiPropertyConstants.MESSAGE_HANDLER_THREAD_POOL_SIZE_DEFAULT;
+import static org.onosproject.net.packet.PacketEvent.Type.EMIT;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Distributed virtual packet store implementation allowing packets to be sent to
+ * remote instances.  Implementation is based on DistributedPacketStore class.
+ */
+@Component(immediate = true, enabled = false, service = VirtualNetworkPacketStore.class,
+        property = {
+                 MESSAGE_HANDLER_THREAD_POOL_SIZE + ":Integer=" + MESSAGE_HANDLER_THREAD_POOL_SIZE_DEFAULT,
+        })
+public class DistributedVirtualPacketStore
+        extends AbstractVirtualStore<PacketEvent, PacketStoreDelegate>
+        implements VirtualNetworkPacketStore {
+
+    private final Logger log = getLogger(getClass());
+
+    private static final String FORMAT = "Setting: messageHandlerThreadPoolSize={}";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ClusterCommunicationService communicationService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ComponentConfigService cfgService;
+
+    private PacketRequestTracker tracker;
+
+    private static final MessageSubject PACKET_OUT_SUBJECT =
+            new MessageSubject("virtual-packet-out");
+
+    private static final Serializer SERIALIZER = Serializer.using(KryoNamespaces.API);
+
+    private ExecutorService messageHandlingExecutor;
+
+    /** Size of thread pool to assign message handler. */
+    private static int messageHandlerThreadPoolSize = MESSAGE_HANDLER_THREAD_POOL_SIZE_DEFAULT;
+
+    @Activate
+    public void activate(ComponentContext context) {
+        cfgService.registerProperties(getClass());
+
+        modified(context);
+
+        messageHandlingExecutor = Executors.newFixedThreadPool(
+                messageHandlerThreadPoolSize,
+                groupedThreads("onos/store/packet", "message-handlers", log));
+
+        communicationService.<OutboundPacketWrapper>addSubscriber(PACKET_OUT_SUBJECT,
+                SERIALIZER::decode,
+                packetWrapper -> notifyDelegate(packetWrapper.networkId,
+                                                new PacketEvent(EMIT,
+                                                                packetWrapper.outboundPacket)),
+                messageHandlingExecutor);
+
+        tracker = new PacketRequestTracker();
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        cfgService.unregisterProperties(getClass(), false);
+        communicationService.removeSubscriber(PACKET_OUT_SUBJECT);
+        messageHandlingExecutor.shutdown();
+        tracker = null;
+        log.info("Stopped");
+    }
+
+    @Modified
+    public void  modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
+
+        int newMessageHandlerThreadPoolSize;
+
+        try {
+            String s = get(properties, MESSAGE_HANDLER_THREAD_POOL_SIZE);
+
+            newMessageHandlerThreadPoolSize =
+                    isNullOrEmpty(s) ? messageHandlerThreadPoolSize : Integer.parseInt(s.trim());
+
+        } catch (NumberFormatException e) {
+            log.warn(e.getMessage());
+            newMessageHandlerThreadPoolSize = messageHandlerThreadPoolSize;
+        }
+
+        // Any change in the following parameters implies thread pool restart
+        if (newMessageHandlerThreadPoolSize != messageHandlerThreadPoolSize) {
+            setMessageHandlerThreadPoolSize(newMessageHandlerThreadPoolSize);
+            restartMessageHandlerThreadPool();
+        }
+
+        log.info(FORMAT, messageHandlerThreadPoolSize);
+    }
+
+    @Override
+    public void emit(NetworkId networkId, OutboundPacket packet) {
+        NodeId myId = clusterService.getLocalNode().id();
+        // TODO revive this when there is MastershipService support for virtual devices
+//        NodeId master = mastershipService.getMasterFor(packet.sendThrough());
+//
+//        if (master == null) {
+//            log.warn("No master found for {}", packet.sendThrough());
+//            return;
+//        }
+//
+//        log.debug("master {} found for {}", myId, packet.sendThrough());
+//        if (myId.equals(master)) {
+//            notifyDelegate(networkId, new PacketEvent(EMIT, packet));
+//            return;
+//        }
+//
+//        communicationService.unicast(packet, PACKET_OUT_SUBJECT, SERIALIZER::encode, master)
+//                            .whenComplete((r, error) -> {
+//                                if (error != null) {
+//                                    log.warn("Failed to send packet-out to {}", master, error);
+//                                }
+//                            });
+    }
+
+    @Override
+    public void requestPackets(NetworkId networkId, PacketRequest request) {
+        tracker.add(networkId, request);
+
+    }
+
+    @Override
+    public void cancelPackets(NetworkId networkId, PacketRequest request) {
+        tracker.remove(networkId, request);
+    }
+
+    @Override
+    public List<PacketRequest> existingRequests(NetworkId networkId) {
+        return tracker.requests(networkId);
+    }
+
+    private final class PacketRequestTracker {
+
+        private ConsistentMap<NetworkId, Map<RequestKey, Set<PacketRequest>>> distRequests;
+        private Map<NetworkId, Map<RequestKey, Set<PacketRequest>>> requests;
+
+        private PacketRequestTracker() {
+            distRequests = storageService.<NetworkId, Map<RequestKey, Set<PacketRequest>>>consistentMapBuilder()
+                    .withName("onos-virtual-packet-requests")
+                    .withSerializer(Serializer.using(KryoNamespace.newBuilder()
+                            .register(KryoNamespaces.API)
+                            .register(RequestKey.class)
+                            .register(NetworkId.class)
+                            .build()))
+                    .build();
+            requests = distRequests.asJavaMap();
+        }
+
+        private void add(NetworkId networkId, PacketRequest request) {
+            AtomicBoolean firstRequest = addInternal(networkId, request);
+            PacketStoreDelegate delegate = delegateMap.get(networkId);
+            if (firstRequest.get() && delegate != null) {
+                // The instance that makes the first request will push to all devices
+                delegate.requestPackets(request);
+            }
+        }
+
+        private AtomicBoolean addInternal(NetworkId networkId, PacketRequest request) {
+            AtomicBoolean firstRequest = new AtomicBoolean(false);
+            AtomicBoolean changed = new AtomicBoolean(true);
+            Map<RequestKey, Set<PacketRequest>> requestsForNetwork = getMap(networkId);
+            requestsForNetwork.compute(key(request), (s, existingRequests) -> {
+                // Reset to false just in case this is a retry due to
+                // ConcurrentModificationException
+                firstRequest.set(false);
+                if (existingRequests == null) {
+                    firstRequest.set(true);
+                    return ImmutableSet.of(request);
+                } else if (!existingRequests.contains(request)) {
+                    firstRequest.set(true);
+                    return ImmutableSet.<PacketRequest>builder()
+                                       .addAll(existingRequests)
+                                       .add(request)
+                                       .build();
+                } else {
+                    changed.set(false);
+                    return existingRequests;
+                }
+            });
+            if (changed.get()) {
+                requests.put(networkId, requestsForNetwork);
+            }
+            return firstRequest;
+        }
+
+        private void remove(NetworkId networkId, PacketRequest request) {
+            AtomicBoolean removedLast = removeInternal(networkId, request);
+            PacketStoreDelegate delegate = delegateMap.get(networkId);
+            if (removedLast.get() && delegate != null) {
+                // The instance that removes the last request will remove from all devices
+                delegate.cancelPackets(request);
+            }
+        }
+
+        private AtomicBoolean removeInternal(NetworkId networkId, PacketRequest request) {
+            AtomicBoolean removedLast = new AtomicBoolean(false);
+            AtomicBoolean changed = new AtomicBoolean(true);
+            Map<RequestKey, Set<PacketRequest>> requestsForNetwork = getMap(networkId);
+            requestsForNetwork.computeIfPresent(key(request), (s, existingRequests) -> {
+                // Reset to false just in case this is a retry due to
+                // ConcurrentModificationException
+                removedLast.set(false);
+                if (existingRequests.contains(request)) {
+                    Set<PacketRequest> newRequests = Sets.newHashSet(existingRequests);
+                    newRequests.remove(request);
+                    if (newRequests.size() > 0) {
+                        return ImmutableSet.copyOf(newRequests);
+                    } else {
+                        removedLast.set(true);
+                        return null;
+                    }
+                } else {
+                    changed.set(false);
+                    return existingRequests;
+                }
+            });
+            if (changed.get()) {
+                requests.put(networkId, requestsForNetwork);
+            }
+            return removedLast;
+        }
+
+        private List<PacketRequest> requests(NetworkId networkId) {
+            Map<RequestKey, Set<PacketRequest>> requestsForNetwork = getMap(networkId);
+            List<PacketRequest> list = Lists.newArrayList();
+            requestsForNetwork.values().forEach(v -> list.addAll(v));
+            list.sort((o1, o2) -> o1.priority().priorityValue() - o2.priority().priorityValue());
+            return list;
+        }
+
+        /*
+         * Gets PacketRequests for specified networkId.
+         */
+        private Map<RequestKey, Set<PacketRequest>> getMap(NetworkId networkId) {
+            return requests.computeIfAbsent(networkId, networkId1 -> {
+                        log.debug("Creating new map for {}", networkId1);
+                        Map newMap = Maps.newHashMap();
+                        return newMap;
+                    });
+        }
+    }
+
+    /**
+     * Creates a new request key from a packet request.
+     *
+     * @param request packet request
+     * @return request key
+     */
+    private static RequestKey key(PacketRequest request) {
+        return new RequestKey(request.selector(), request.priority());
+    }
+
+    /**
+     * Key of a packet request.
+     */
+    private static final class RequestKey {
+        private final TrafficSelector selector;
+        private final PacketPriority priority;
+
+        private RequestKey(TrafficSelector selector, PacketPriority priority) {
+            this.selector = selector;
+            this.priority = priority;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(selector, priority);
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other == this) {
+                return true;
+            }
+
+            if (!(other instanceof RequestKey)) {
+                return false;
+            }
+
+            RequestKey that = (RequestKey) other;
+
+            return Objects.equals(selector, that.selector) &&
+                    Objects.equals(priority, that.priority);
+        }
+    }
+
+    private static OutboundPacketWrapper wrapper(NetworkId networkId, OutboundPacket outboundPacket) {
+        return new OutboundPacketWrapper(networkId, outboundPacket);
+    }
+
+    /*
+     * OutboundPacket in
+     */
+    private static final class OutboundPacketWrapper {
+        private NetworkId networkId;
+        private OutboundPacket outboundPacket;
+
+        private OutboundPacketWrapper(NetworkId networkId, OutboundPacket outboundPacket) {
+            this.networkId = networkId;
+            this.outboundPacket = outboundPacket;
+        }
+
+    }
+
+    /**
+     * Sets thread pool size of message handler.
+     *
+     * @param poolSize
+     */
+    private void setMessageHandlerThreadPoolSize(int poolSize) {
+        checkArgument(poolSize >= 0, "Message handler pool size must be 0 or more");
+        messageHandlerThreadPoolSize = poolSize;
+    }
+
+    /**
+     * Restarts thread pool of message handler.
+     */
+    private void restartMessageHandlerThreadPool() {
+        ExecutorService prevExecutor = messageHandlingExecutor;
+        messageHandlingExecutor = newFixedThreadPool(getMessageHandlerThreadPoolSize(),
+                                                     groupedThreads("DistPktStore", "messageHandling-%d", log));
+        prevExecutor.shutdown();
+    }
+
+    /**
+     * Gets current thread pool size of message handler.
+     *
+     * @return messageHandlerThreadPoolSize
+     */
+    private int getMessageHandlerThreadPoolSize() {
+        return messageHandlerThreadPoolSize;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/MeterData.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/MeterData.java
new file mode 100644
index 0000000..c014505
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/MeterData.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018-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.store.impl;
+
+import org.onosproject.cluster.NodeId;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterFailReason;
+
+import java.util.Optional;
+
+/**
+ * A class representing the meter information stored in the meter store.
+ */
+public class MeterData {
+
+    private final Meter meter;
+    private final Optional<MeterFailReason> reason;
+    private final NodeId origin;
+
+    public MeterData(Meter meter, MeterFailReason reason, NodeId origin) {
+        this.meter = meter;
+        this.reason = Optional.ofNullable(reason);
+        this.origin = origin;
+    }
+
+    public Meter meter() {
+        return meter;
+    }
+
+    public Optional<MeterFailReason> reason() {
+        return this.reason;
+    }
+
+    public NodeId origin() {
+        return this.origin;
+    }
+
+
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/OsgiPropertyConstants.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/OsgiPropertyConstants.java
new file mode 100644
index 0000000..39bc5b0
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/OsgiPropertyConstants.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2018-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.store.impl;
+
+/**
+ * Constants for default values of configurable properties.
+ */
+public final class OsgiPropertyConstants {
+
+    private OsgiPropertyConstants() {}
+
+    public static final String MESSAGE_HANDLER_THREAD_POOL_SIZE = "messageHandlerThreadPoolSize";
+    public static final int MESSAGE_HANDLER_THREAD_POOL_SIZE_DEFAULT = 4;
+
+    public static final String BACKUP_PERIOD_MILLIS = "backupPeriod";
+    public static final int BACKUP_PERIOD_MILLIS_DEFAULT = 2000;
+
+    public static final String PERSISTENCE_ENABLED = "persistenceEnabled";
+    public static final boolean PERSISTENCE_ENABLED_DEFAULT = false;
+
+    public static final String PENDING_FUTURE_TIMEOUT_MINUTES = "pendingFutureTimeoutMinutes";
+    public static final int PENDING_FUTURE_TIMEOUT_MINUTES_DEFAULT = 5;
+
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualFlowObjectiveStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualFlowObjectiveStore.java
new file mode 100644
index 0000000..4ef268e
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualFlowObjectiveStore.java
@@ -0,0 +1,172 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.collect.Maps;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
+import org.onosproject.net.behaviour.DefaultNextGroup;
+import org.onosproject.net.behaviour.NextGroup;
+import org.onosproject.net.flowobjective.FlowObjectiveStoreDelegate;
+import org.onosproject.net.flowobjective.ObjectiveEvent;
+import org.onosproject.store.service.AtomicCounter;
+import org.onosproject.store.service.StorageService;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import static org.onlab.util.Tools.groupedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Single instance implementation of store to manage
+ * the inventory of created next groups for virtual network.
+ */
+@Component(immediate = true, service = VirtualNetworkFlowObjectiveStore.class)
+public class SimpleVirtualFlowObjectiveStore
+        extends AbstractVirtualStore<ObjectiveEvent, FlowObjectiveStoreDelegate>
+        implements VirtualNetworkFlowObjectiveStore {
+
+    private final Logger log = getLogger(getClass());
+
+    private ConcurrentMap<NetworkId, ConcurrentMap<Integer, byte[]>> nextGroupsMap;
+
+    private AtomicCounter nextIds;
+
+    // event queue to separate map-listener threads from event-handler threads (tpool)
+    private BlockingQueue<VirtualObjectiveEvent> eventQ;
+    private ExecutorService tpool;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected StorageService storageService;
+
+    @Activate
+    public void activate() {
+        tpool = Executors.newFixedThreadPool(4, groupedThreads("onos/virtual/flobj-notifier", "%d", log));
+        eventQ = new LinkedBlockingQueue<>();
+        tpool.execute(new FlowObjectiveNotifier());
+
+        initNextGroupsMap();
+
+        nextIds = storageService.getAtomicCounter("next-objective-counter");
+        log.info("Started");
+    }
+
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    protected void initNextGroupsMap() {
+        nextGroupsMap = Maps.newConcurrentMap();
+    }
+
+    protected void updateNextGroupsMap(NetworkId networkId,
+                                       ConcurrentMap<Integer, byte[]> nextGroups) {
+    }
+
+    protected ConcurrentMap<Integer, byte[]> getNextGroups(NetworkId networkId) {
+        nextGroupsMap.computeIfAbsent(networkId, n -> Maps.newConcurrentMap());
+        return nextGroupsMap.get(networkId);
+    }
+
+    @Override
+    public void putNextGroup(NetworkId networkId, Integer nextId, NextGroup group) {
+        ConcurrentMap<Integer, byte[]> nextGroups = getNextGroups(networkId);
+        nextGroups.put(nextId, group.data());
+        updateNextGroupsMap(networkId, nextGroups);
+
+        eventQ.add(new VirtualObjectiveEvent(networkId, ObjectiveEvent.Type.ADD, nextId));
+    }
+
+    @Override
+    public NextGroup getNextGroup(NetworkId networkId, Integer nextId) {
+        ConcurrentMap<Integer, byte[]> nextGroups = getNextGroups(networkId);
+        byte[] groupData = nextGroups.get(nextId);
+        if (groupData != null) {
+            return new DefaultNextGroup(groupData);
+        }
+        return null;
+    }
+
+    @Override
+    public NextGroup removeNextGroup(NetworkId networkId, Integer nextId) {
+        ConcurrentMap<Integer, byte[]> nextGroups = getNextGroups(networkId);
+        byte[] nextGroup = nextGroups.remove(nextId);
+        updateNextGroupsMap(networkId, nextGroups);
+
+        eventQ.add(new VirtualObjectiveEvent(networkId, ObjectiveEvent.Type.REMOVE, nextId));
+
+        return new DefaultNextGroup(nextGroup);
+    }
+
+    @Override
+    public Map<Integer, NextGroup> getAllGroups(NetworkId networkId) {
+        ConcurrentMap<Integer, byte[]> nextGroups = getNextGroups(networkId);
+
+        Map<Integer, NextGroup> nextGroupMappings = new HashMap<>();
+        for (int key : nextGroups.keySet()) {
+            NextGroup nextGroup = getNextGroup(networkId, key);
+            if (nextGroup != null) {
+                nextGroupMappings.put(key, nextGroup);
+            }
+        }
+        return nextGroupMappings;
+    }
+
+    @Override
+    public int allocateNextId(NetworkId networkId) {
+        return (int) nextIds.incrementAndGet();
+    }
+
+    private class FlowObjectiveNotifier implements Runnable {
+        @Override
+        public void run() {
+            try {
+                while (!Thread.currentThread().isInterrupted()) {
+                    VirtualObjectiveEvent vEvent = eventQ.take();
+                    notifyDelegate(vEvent.networkId(), vEvent);
+                }
+            } catch (InterruptedException ex) {
+                Thread.currentThread().interrupt();
+            }
+        }
+    }
+
+    private class VirtualObjectiveEvent extends ObjectiveEvent {
+        NetworkId networkId;
+
+        public VirtualObjectiveEvent(NetworkId networkId, Type type,
+                                     Integer objective) {
+            super(type, objective);
+            this.networkId = networkId;
+        }
+
+        NetworkId networkId() {
+            return networkId;
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualFlowRuleStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualFlowRuleStore.java
new file mode 100644
index 0000000..1fc5cde
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualFlowRuleStore.java
@@ -0,0 +1,411 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.RemovalListener;
+import com.google.common.cache.RemovalNotification;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.SettableFuture;
+import org.onlab.util.Tools;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+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.FlowId;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleStoreDelegate;
+import org.onosproject.net.flow.StoredFlowEntry;
+import org.onosproject.net.flow.TableStatisticsEntry;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchEntry;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchEvent;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchRequest;
+import org.onosproject.store.service.StorageService;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.onosproject.incubator.net.virtual.store.impl.OsgiPropertyConstants.PENDING_FUTURE_TIMEOUT_MINUTES;
+import static org.onosproject.incubator.net.virtual.store.impl.OsgiPropertyConstants.PENDING_FUTURE_TIMEOUT_MINUTES_DEFAULT;
+import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of the virtual network flow rule store to manage inventory of
+ * virtual flow rules using trivial in-memory implementation.
+ */
+//TODO: support distributed flowrule store for virtual networks
+
+@Component(immediate = true, service = VirtualNetworkFlowRuleStore.class,
+        property = {
+                 PENDING_FUTURE_TIMEOUT_MINUTES + ":Integer=" + PENDING_FUTURE_TIMEOUT_MINUTES_DEFAULT,
+        })
+public class SimpleVirtualFlowRuleStore
+        extends AbstractVirtualStore<FlowRuleBatchEvent, FlowRuleStoreDelegate>
+        implements VirtualNetworkFlowRuleStore {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected StorageService storageService;
+
+    private final ConcurrentMap<NetworkId,
+            ConcurrentMap<DeviceId, ConcurrentMap<FlowId, List<StoredFlowEntry>>>>
+            flowEntries = new ConcurrentHashMap<>();
+
+
+    private final AtomicInteger localBatchIdGen = new AtomicInteger();
+
+    /** Expiration time after an entry is created that it should be automatically removed. */
+    private int pendingFutureTimeoutMinutes = PENDING_FUTURE_TIMEOUT_MINUTES_DEFAULT;
+
+    private Cache<Integer, SettableFuture<CompletedBatchOperation>> pendingFutures =
+            CacheBuilder.newBuilder()
+                    .expireAfterWrite(pendingFutureTimeoutMinutes, TimeUnit.MINUTES)
+                    .removalListener(new TimeoutFuture())
+                    .build();
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        flowEntries.clear();
+        log.info("Stopped");
+    }
+
+    @Modified
+    public void modified(ComponentContext context) {
+
+        readComponentConfiguration(context);
+
+        // Reset Cache and copy all.
+        Cache<Integer, SettableFuture<CompletedBatchOperation>> prevFutures = pendingFutures;
+        pendingFutures = CacheBuilder.newBuilder()
+                .expireAfterWrite(pendingFutureTimeoutMinutes, TimeUnit.MINUTES)
+                .removalListener(new TimeoutFuture())
+                .build();
+
+        pendingFutures.putAll(prevFutures.asMap());
+    }
+
+    /**
+     * Extracts properties from the component configuration context.
+     *
+     * @param context the component context
+     */
+    private void readComponentConfiguration(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+
+        Integer newPendingFutureTimeoutMinutes =
+                Tools.getIntegerProperty(properties, "pendingFutureTimeoutMinutes");
+        if (newPendingFutureTimeoutMinutes == null) {
+            pendingFutureTimeoutMinutes = PENDING_FUTURE_TIMEOUT_MINUTES_DEFAULT;
+            log.info("Pending future timeout is not configured, " +
+                             "using current value of {}", pendingFutureTimeoutMinutes);
+        } else {
+            pendingFutureTimeoutMinutes = newPendingFutureTimeoutMinutes;
+            log.info("Configured. Pending future timeout is configured to {}",
+                     pendingFutureTimeoutMinutes);
+        }
+    }
+
+    @Override
+    public int getFlowRuleCount(NetworkId networkId) {
+        int sum = 0;
+
+        if (flowEntries.get(networkId) == null) {
+            return 0;
+        }
+
+        for (ConcurrentMap<FlowId, List<StoredFlowEntry>> ft :
+                flowEntries.get(networkId).values()) {
+            for (List<StoredFlowEntry> fes : ft.values()) {
+                sum += fes.size();
+            }
+        }
+        return sum;
+    }
+
+    @Override
+    public FlowEntry getFlowEntry(NetworkId networkId, FlowRule rule) {
+        return getFlowEntryInternal(networkId, rule.deviceId(), rule);
+    }
+
+    @Override
+    public Iterable<FlowEntry> getFlowEntries(NetworkId networkId, DeviceId deviceId) {
+        return FluentIterable.from(getFlowTable(networkId, deviceId).values())
+                .transformAndConcat(Collections::unmodifiableList);
+    }
+
+    private void storeFlowRule(NetworkId networkId, FlowRule rule) {
+        storeFlowRuleInternal(networkId, rule);
+    }
+
+    @Override
+    public void storeBatch(NetworkId networkId, FlowRuleBatchOperation batchOperation) {
+        List<FlowRuleBatchEntry> toAdd = new ArrayList<>();
+        List<FlowRuleBatchEntry> toRemove = new ArrayList<>();
+
+        for (FlowRuleBatchEntry entry : batchOperation.getOperations()) {
+            final FlowRule flowRule = entry.target();
+            if (entry.operator().equals(FlowRuleBatchEntry.FlowRuleOperation.ADD)) {
+                if (!getFlowEntries(networkId, flowRule.deviceId(),
+                                    flowRule.id()).contains(flowRule)) {
+                    storeFlowRule(networkId, flowRule);
+                    toAdd.add(entry);
+                }
+            } else if (entry.operator().equals(FlowRuleBatchEntry.FlowRuleOperation.REMOVE)) {
+                if (getFlowEntries(networkId, flowRule.deviceId(), flowRule.id()).contains(flowRule)) {
+                    deleteFlowRule(networkId, flowRule);
+                    toRemove.add(entry);
+                }
+            } else {
+                throw new UnsupportedOperationException("Unsupported operation type");
+            }
+        }
+
+        if (toAdd.isEmpty() && toRemove.isEmpty()) {
+            notifyDelegate(networkId, FlowRuleBatchEvent.completed(
+                    new FlowRuleBatchRequest(batchOperation.id(), Collections.emptySet()),
+                    new CompletedBatchOperation(true, Collections.emptySet(),
+                                                batchOperation.deviceId())));
+            return;
+        }
+
+        SettableFuture<CompletedBatchOperation> r = SettableFuture.create();
+        final int futureId = localBatchIdGen.incrementAndGet();
+
+        pendingFutures.put(futureId, r);
+
+        toAdd.addAll(toRemove);
+        notifyDelegate(networkId, FlowRuleBatchEvent.requested(
+                new FlowRuleBatchRequest(batchOperation.id(),
+                                         Sets.newHashSet(toAdd)), batchOperation.deviceId()));
+
+    }
+
+    @Override
+    public void batchOperationComplete(NetworkId networkId, FlowRuleBatchEvent event) {
+        final Long batchId = event.subject().batchId();
+        SettableFuture<CompletedBatchOperation> future
+                = pendingFutures.getIfPresent(batchId);
+        if (future != null) {
+            future.set(event.result());
+            pendingFutures.invalidate(batchId);
+        }
+        notifyDelegate(networkId, event);
+    }
+
+    @Override
+    public void deleteFlowRule(NetworkId networkId, FlowRule rule) {
+        List<StoredFlowEntry> entries = getFlowEntries(networkId, rule.deviceId(), rule.id());
+
+        synchronized (entries) {
+            for (StoredFlowEntry entry : entries) {
+                if (entry.equals(rule)) {
+                    synchronized (entry) {
+                        entry.setState(FlowEntry.FlowEntryState.PENDING_REMOVE);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public FlowRuleEvent addOrUpdateFlowRule(NetworkId networkId, FlowEntry rule) {
+        // check if this new rule is an update to an existing entry
+        List<StoredFlowEntry> entries = getFlowEntries(networkId, rule.deviceId(), rule.id());
+        synchronized (entries) {
+            for (StoredFlowEntry stored : entries) {
+                if (stored.equals(rule)) {
+                    synchronized (stored) {
+                        //FIXME modification of "stored" flow entry outside of flow table
+                        stored.setBytes(rule.bytes());
+                        stored.setLife(rule.life());
+                        stored.setPackets(rule.packets());
+                        if (stored.state() == FlowEntry.FlowEntryState.PENDING_ADD) {
+                            stored.setState(FlowEntry.FlowEntryState.ADDED);
+                            // TODO: Do we need to change `rule` state?
+                            return new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED, rule);
+                        }
+                        return new FlowRuleEvent(FlowRuleEvent.Type.RULE_UPDATED, rule);
+                    }
+                }
+            }
+        }
+
+        // should not reach here
+        // storeFlowRule was expected to be called
+        log.error("FlowRule was not found in store {} to update", rule);
+
+        return null;
+    }
+
+    @Override
+    public FlowRuleEvent removeFlowRule(NetworkId networkId, FlowEntry rule) {
+        // This is where one could mark a rule as removed and still keep it in the store.
+        final DeviceId did = rule.deviceId();
+
+        List<StoredFlowEntry> entries = getFlowEntries(networkId, did, rule.id());
+        synchronized (entries) {
+            if (entries.remove(rule)) {
+                return new FlowRuleEvent(RULE_REMOVED, rule);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public FlowRuleEvent pendingFlowRule(NetworkId networkId, FlowEntry rule) {
+        List<StoredFlowEntry> entries = getFlowEntries(networkId, rule.deviceId(), rule.id());
+        synchronized (entries) {
+            for (StoredFlowEntry entry : entries) {
+                if (entry.equals(rule) &&
+                        entry.state() != FlowEntry.FlowEntryState.PENDING_ADD) {
+                    synchronized (entry) {
+                        entry.setState(FlowEntry.FlowEntryState.PENDING_ADD);
+                        return new FlowRuleEvent(FlowRuleEvent.Type.RULE_UPDATED, rule);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void purgeFlowRule(NetworkId networkId, DeviceId deviceId) {
+        flowEntries.get(networkId).remove(deviceId);
+    }
+
+    @Override
+    public void purgeFlowRules(NetworkId networkId) {
+        flowEntries.get(networkId).clear();
+    }
+
+    @Override
+    public FlowRuleEvent
+    updateTableStatistics(NetworkId networkId, DeviceId deviceId, List<TableStatisticsEntry> tableStats) {
+        //TODO: Table operations are not supported yet
+        return null;
+    }
+
+    @Override
+    public Iterable<TableStatisticsEntry>
+    getTableStatistics(NetworkId networkId, DeviceId deviceId) {
+        //TODO: Table operations are not supported yet
+        return null;
+    }
+
+    /**
+     * Returns the flow table for specified device.
+     *
+     * @param networkId identifier of the virtual network
+     * @param deviceId identifier of the virtual device
+     * @return Map representing Flow Table of given device.
+     */
+    private ConcurrentMap<FlowId, List<StoredFlowEntry>>
+    getFlowTable(NetworkId networkId, DeviceId deviceId) {
+        return flowEntries
+                .computeIfAbsent(networkId, n -> new ConcurrentHashMap<>())
+                .computeIfAbsent(deviceId, k -> new ConcurrentHashMap<>());
+    }
+
+    private List<StoredFlowEntry>
+    getFlowEntries(NetworkId networkId, DeviceId deviceId, FlowId flowId) {
+        final ConcurrentMap<FlowId, List<StoredFlowEntry>> flowTable
+                = getFlowTable(networkId, deviceId);
+
+        List<StoredFlowEntry> r = flowTable.get(flowId);
+        if (r == null) {
+            final List<StoredFlowEntry> concurrentlyAdded;
+            r = new CopyOnWriteArrayList<>();
+            concurrentlyAdded = flowTable.putIfAbsent(flowId, r);
+            if (concurrentlyAdded != null) {
+                return concurrentlyAdded;
+            }
+        }
+        return r;
+    }
+
+    private FlowEntry
+    getFlowEntryInternal(NetworkId networkId, DeviceId deviceId, FlowRule rule) {
+        List<StoredFlowEntry> fes = getFlowEntries(networkId, deviceId, rule.id());
+        for (StoredFlowEntry fe : fes) {
+            if (fe.equals(rule)) {
+                return fe;
+            }
+        }
+        return null;
+    }
+
+    private void storeFlowRuleInternal(NetworkId networkId, FlowRule rule) {
+        StoredFlowEntry f = new DefaultFlowEntry(rule);
+        final DeviceId did = f.deviceId();
+        final FlowId fid = f.id();
+        List<StoredFlowEntry> existing = getFlowEntries(networkId, did, fid);
+        synchronized (existing) {
+            for (StoredFlowEntry fe : existing) {
+                if (fe.equals(rule)) {
+                    // was already there? ignore
+                    return;
+                }
+            }
+            // new flow rule added
+            existing.add(f);
+        }
+    }
+
+    private static final class TimeoutFuture
+            implements RemovalListener<Integer, SettableFuture<CompletedBatchOperation>> {
+        @Override
+        public void onRemoval(RemovalNotification<Integer,
+                SettableFuture<CompletedBatchOperation>> notification) {
+            // wrapping in ExecutionException to support Future.get
+            if (notification.wasEvicted()) {
+                notification.getValue()
+                        .setException(new ExecutionException("Timed out",
+                                                             new TimeoutException()));
+            }
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualGroupStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualGroupStore.java
new file mode 100644
index 0000000..3c696ce
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualGroupStore.java
@@ -0,0 +1,764 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Sets;
+import org.onosproject.core.GroupId;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkGroupStore;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.group.DefaultGroup;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupEvent;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupOperation;
+import org.onosproject.net.group.GroupStoreDelegate;
+import org.onosproject.net.group.StoredGroupBucketEntry;
+import org.onosproject.net.group.StoredGroupEntry;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Manages inventory of virtual group entries using trivial in-memory implementation.
+ */
+@Component(immediate = true, service = VirtualNetworkGroupStore.class)
+public class SimpleVirtualGroupStore
+        extends AbstractVirtualStore<GroupEvent, GroupStoreDelegate>
+        implements VirtualNetworkGroupStore {
+
+    private final Logger log = getLogger(getClass());
+
+    private final int dummyId = 0xffffffff;
+    private final GroupId dummyGroupId = new GroupId(dummyId);
+
+    // inner Map is per device group table
+    private final ConcurrentMap<NetworkId,
+            ConcurrentMap<DeviceId, ConcurrentMap<GroupKey, StoredGroupEntry>>>
+            groupEntriesByKey = new ConcurrentHashMap<>();
+
+    private final ConcurrentMap<NetworkId,
+            ConcurrentMap<DeviceId, ConcurrentMap<GroupId, StoredGroupEntry>>>
+            groupEntriesById = new ConcurrentHashMap<>();
+
+    private final ConcurrentMap<NetworkId,
+            ConcurrentMap<DeviceId, ConcurrentMap<GroupKey, StoredGroupEntry>>>
+            pendingGroupEntriesByKey = new ConcurrentHashMap<>();
+
+    private final ConcurrentMap<NetworkId,
+            ConcurrentMap<DeviceId, ConcurrentMap<GroupId, Group>>>
+            extraneousGroupEntriesById = new ConcurrentHashMap<>();
+
+    private final ConcurrentMap<NetworkId, HashMap<DeviceId, Boolean>>
+            deviceAuditStatus = new ConcurrentHashMap<>();
+
+    private final AtomicInteger groupIdGen = new AtomicInteger();
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        groupEntriesByKey.clear();
+        groupEntriesById.clear();
+        log.info("Stopped");
+    }
+
+    /**
+     * Returns the group key table for specified device.
+     *
+     * @param networkId identifier of the virtual network
+     * @param deviceId identifier of the device
+     * @return Map representing group key table of given device.
+     */
+    private ConcurrentMap<GroupKey, StoredGroupEntry>
+    getGroupKeyTable(NetworkId networkId, DeviceId deviceId) {
+        groupEntriesByKey.computeIfAbsent(networkId, n -> new ConcurrentHashMap<>());
+        return groupEntriesByKey.get(networkId)
+                .computeIfAbsent(deviceId, k -> new ConcurrentHashMap<>());
+    }
+
+    /**
+     * Returns the group id table for specified device.
+     *
+     * @param networkId identifier of the virtual network
+     * @param deviceId identifier of the device
+     * @return Map representing group key table of given device.
+     */
+    private ConcurrentMap<GroupId, StoredGroupEntry>
+    getGroupIdTable(NetworkId networkId, DeviceId deviceId) {
+        groupEntriesById.computeIfAbsent(networkId, n -> new ConcurrentHashMap<>());
+        return groupEntriesById.get(networkId)
+                .computeIfAbsent(deviceId, k -> new ConcurrentHashMap<>());
+    }
+
+    /**
+     * Returns the pending group key table for specified device.
+     *
+     * @param networkId identifier of the virtual network
+     * @param deviceId identifier of the device
+     * @return Map representing group key table of given device.
+     */
+    private ConcurrentMap<GroupKey, StoredGroupEntry>
+    getPendingGroupKeyTable(NetworkId networkId, DeviceId deviceId) {
+        pendingGroupEntriesByKey.computeIfAbsent(networkId, n -> new ConcurrentHashMap<>());
+        return pendingGroupEntriesByKey.get(networkId)
+                .computeIfAbsent(deviceId, k -> new ConcurrentHashMap<>());
+    }
+
+    /**
+     * Returns the extraneous group id table for specified device.
+     *
+     * @param networkId identifier of the virtual network
+     * @param deviceId identifier of the device
+     * @return Map representing group key table of given device.
+     */
+    private ConcurrentMap<GroupId, Group>
+    getExtraneousGroupIdTable(NetworkId networkId, DeviceId deviceId) {
+        extraneousGroupEntriesById.computeIfAbsent(networkId, n -> new ConcurrentHashMap<>());
+        return extraneousGroupEntriesById.get(networkId)
+                .computeIfAbsent(deviceId, k -> new ConcurrentHashMap<>());
+    }
+
+    @Override
+    public int getGroupCount(NetworkId networkId, DeviceId deviceId) {
+        return (groupEntriesByKey.get(networkId).get(deviceId) != null) ?
+                groupEntriesByKey.get(networkId).get(deviceId).size() : 0;
+    }
+
+    @Override
+    public Iterable<Group> getGroups(NetworkId networkId, DeviceId deviceId) {
+        // flatten and make iterator unmodifiable
+        return FluentIterable.from(getGroupKeyTable(networkId, deviceId).values())
+                .transform(input -> input);
+    }
+
+    @Override
+    public Group getGroup(NetworkId networkId, DeviceId deviceId, GroupKey appCookie) {
+        if (groupEntriesByKey.get(networkId) != null &&
+                groupEntriesByKey.get(networkId).get(deviceId) != null) {
+            return groupEntriesByKey.get(networkId).get(deviceId).get(appCookie);
+        }
+        return null;
+    }
+
+    @Override
+    public Group getGroup(NetworkId networkId, DeviceId deviceId, GroupId groupId) {
+        if (groupEntriesById.get(networkId) != null &&
+                groupEntriesById.get(networkId).get(deviceId) != null) {
+            return groupEntriesById.get(networkId).get(deviceId).get(groupId);
+        }
+        return null;
+    }
+
+    private int getFreeGroupIdValue(NetworkId networkId, DeviceId deviceId) {
+        int freeId = groupIdGen.incrementAndGet();
+
+        while (true) {
+            Group existing = null;
+            if (groupEntriesById.get(networkId) != null &&
+                    groupEntriesById.get(networkId).get(deviceId) != null) {
+                existing = groupEntriesById.get(networkId).get(deviceId)
+                                .get(new GroupId(freeId));
+            }
+
+            if (existing == null) {
+                if (extraneousGroupEntriesById.get(networkId) != null &&
+                        extraneousGroupEntriesById.get(networkId).get(deviceId) != null) {
+                    existing = extraneousGroupEntriesById.get(networkId).get(deviceId)
+                                    .get(new GroupId(freeId));
+                }
+            }
+
+            if (existing != null) {
+                freeId = groupIdGen.incrementAndGet();
+            } else {
+                break;
+            }
+        }
+        return freeId;
+    }
+
+    @Override
+    public void storeGroupDescription(NetworkId networkId, GroupDescription groupDesc) {
+        // Check if a group is existing with the same key
+        if (getGroup(networkId, groupDesc.deviceId(), groupDesc.appCookie()) != null) {
+            return;
+        }
+
+        if (deviceAuditStatus.get(networkId) == null ||
+                deviceAuditStatus.get(networkId).get(groupDesc.deviceId()) == null) {
+            // Device group audit has not completed yet
+            // Add this group description to pending group key table
+            // Create a group entry object with Dummy Group ID
+            StoredGroupEntry group = new DefaultGroup(dummyGroupId, groupDesc);
+            group.setState(Group.GroupState.WAITING_AUDIT_COMPLETE);
+            ConcurrentMap<GroupKey, StoredGroupEntry> pendingKeyTable =
+                    getPendingGroupKeyTable(networkId, groupDesc.deviceId());
+            pendingKeyTable.put(groupDesc.appCookie(), group);
+            return;
+        }
+
+        storeGroupDescriptionInternal(networkId, groupDesc);
+    }
+
+    private void storeGroupDescriptionInternal(NetworkId networkId,
+                                               GroupDescription groupDesc) {
+        // Check if a group is existing with the same key
+        if (getGroup(networkId, groupDesc.deviceId(), groupDesc.appCookie()) != null) {
+            return;
+        }
+
+        GroupId id = null;
+        if (groupDesc.givenGroupId() == null) {
+            // Get a new group identifier
+            id = new GroupId(getFreeGroupIdValue(networkId, groupDesc.deviceId()));
+        } else {
+            id = new GroupId(groupDesc.givenGroupId());
+        }
+        // Create a group entry object
+        StoredGroupEntry group = new DefaultGroup(id, groupDesc);
+        // Insert the newly created group entry into concurrent key and id maps
+        ConcurrentMap<GroupKey, StoredGroupEntry> keyTable =
+                getGroupKeyTable(networkId, groupDesc.deviceId());
+        keyTable.put(groupDesc.appCookie(), group);
+        ConcurrentMap<GroupId, StoredGroupEntry> idTable =
+                getGroupIdTable(networkId, groupDesc.deviceId());
+        idTable.put(id, group);
+        notifyDelegate(networkId, new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED,
+                                      group));
+    }
+
+    @Override
+    public void updateGroupDescription(NetworkId networkId, DeviceId deviceId,
+                                       GroupKey oldAppCookie, UpdateType type,
+                                       GroupBuckets newBuckets, GroupKey newAppCookie) {
+        // Check if a group is existing with the provided key
+        Group oldGroup = getGroup(networkId, deviceId, oldAppCookie);
+        if (oldGroup == null) {
+            return;
+        }
+
+        List<GroupBucket> newBucketList = getUpdatedBucketList(oldGroup,
+                                                               type,
+                                                               newBuckets);
+        if (newBucketList != null) {
+            // Create a new group object from the old group
+            GroupBuckets updatedBuckets = new GroupBuckets(newBucketList);
+            GroupKey newCookie = (newAppCookie != null) ? newAppCookie : oldAppCookie;
+            GroupDescription updatedGroupDesc = new DefaultGroupDescription(
+                    oldGroup.deviceId(),
+                    oldGroup.type(),
+                    updatedBuckets,
+                    newCookie,
+                    oldGroup.givenGroupId(),
+                    oldGroup.appId());
+            StoredGroupEntry newGroup = new DefaultGroup(oldGroup.id(),
+                                                         updatedGroupDesc);
+            newGroup.setState(Group.GroupState.PENDING_UPDATE);
+            newGroup.setLife(oldGroup.life());
+            newGroup.setPackets(oldGroup.packets());
+            newGroup.setBytes(oldGroup.bytes());
+
+            // Remove the old entry from maps and add new entry using new key
+            ConcurrentMap<GroupKey, StoredGroupEntry> keyTable =
+                    getGroupKeyTable(networkId, oldGroup.deviceId());
+            ConcurrentMap<GroupId, StoredGroupEntry> idTable =
+                    getGroupIdTable(networkId, oldGroup.deviceId());
+            keyTable.remove(oldGroup.appCookie());
+            idTable.remove(oldGroup.id());
+            keyTable.put(newGroup.appCookie(), newGroup);
+            idTable.put(newGroup.id(), newGroup);
+            notifyDelegate(networkId,
+                           new GroupEvent(GroupEvent.Type.GROUP_UPDATE_REQUESTED,
+                                          newGroup));
+        }
+
+    }
+
+    private List<GroupBucket> getUpdatedBucketList(Group oldGroup,
+                                                   UpdateType type,
+                                                   GroupBuckets buckets) {
+        if (type == UpdateType.SET) {
+            return buckets.buckets();
+        }
+
+        List<GroupBucket> oldBuckets = oldGroup.buckets().buckets();
+        List<GroupBucket> updatedBucketList = new ArrayList<>();
+        boolean groupDescUpdated = false;
+
+        if (type == UpdateType.ADD) {
+            List<GroupBucket> newBuckets = buckets.buckets();
+
+            // Add old buckets that will not be updated and check if any will be updated.
+            for (GroupBucket oldBucket : oldBuckets) {
+                int newBucketIndex = newBuckets.indexOf(oldBucket);
+
+                if (newBucketIndex != -1) {
+                    GroupBucket newBucket = newBuckets.get(newBucketIndex);
+                    if (!newBucket.hasSameParameters(oldBucket)) {
+                        // Bucket will be updated
+                        groupDescUpdated = true;
+                    }
+                } else {
+                    // Old bucket will remain the same - add it.
+                    updatedBucketList.add(oldBucket);
+                }
+            }
+
+            // Add all new buckets
+            updatedBucketList.addAll(newBuckets);
+            if (!oldBuckets.containsAll(newBuckets)) {
+                groupDescUpdated = true;
+            }
+
+        } else if (type == UpdateType.REMOVE) {
+            List<GroupBucket> bucketsToRemove = buckets.buckets();
+
+            // Check which old buckets should remain
+            for (GroupBucket oldBucket : oldBuckets) {
+                if (!bucketsToRemove.contains(oldBucket)) {
+                    updatedBucketList.add(oldBucket);
+                } else {
+                    groupDescUpdated = true;
+                }
+            }
+        }
+
+        if (groupDescUpdated) {
+            return updatedBucketList;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public void deleteGroupDescription(NetworkId networkId, DeviceId deviceId,
+                                       GroupKey appCookie) {
+        // Check if a group is existing with the provided key
+        StoredGroupEntry existing = null;
+        if (groupEntriesByKey.get(networkId) != null &&
+                groupEntriesByKey.get(networkId).get(deviceId) != null) {
+            existing = groupEntriesByKey.get(networkId).get(deviceId).get(appCookie);
+        }
+
+        if (existing == null) {
+            return;
+        }
+
+        synchronized (existing) {
+            existing.setState(Group.GroupState.PENDING_DELETE);
+        }
+        notifyDelegate(networkId,
+                       new GroupEvent(GroupEvent.Type.GROUP_REMOVE_REQUESTED, existing));
+    }
+
+    @Override
+    public void addOrUpdateGroupEntry(NetworkId networkId, Group group) {
+        // check if this new entry is an update to an existing entry
+        StoredGroupEntry existing = null;
+
+        if (groupEntriesById.get(networkId) != null &&
+                groupEntriesById.get(networkId).get(group.deviceId()) != null) {
+            existing = groupEntriesById
+                    .get(networkId)
+                    .get(group.deviceId())
+                    .get(group.id());
+        }
+
+        GroupEvent event = null;
+
+        if (existing != null) {
+            synchronized (existing) {
+                for (GroupBucket bucket:group.buckets().buckets()) {
+                    Optional<GroupBucket> matchingBucket =
+                            existing.buckets().buckets()
+                                    .stream()
+                                    .filter((existingBucket) -> (existingBucket.equals(bucket)))
+                                    .findFirst();
+                    if (matchingBucket.isPresent()) {
+                        ((StoredGroupBucketEntry) matchingBucket.
+                                get()).setPackets(bucket.packets());
+                        ((StoredGroupBucketEntry) matchingBucket.
+                                get()).setBytes(bucket.bytes());
+                    } else {
+                        log.warn("addOrUpdateGroupEntry: No matching "
+                                         + "buckets to update stats");
+                    }
+                }
+                existing.setLife(group.life());
+                existing.setPackets(group.packets());
+                existing.setBytes(group.bytes());
+                if (existing.state() == Group.GroupState.PENDING_ADD) {
+                    existing.setState(Group.GroupState.ADDED);
+                    event = new GroupEvent(GroupEvent.Type.GROUP_ADDED, existing);
+                } else {
+                    if (existing.state() == Group.GroupState.PENDING_UPDATE) {
+                        existing.setState(Group.GroupState.ADDED);
+                    }
+                    event = new GroupEvent(GroupEvent.Type.GROUP_UPDATED, existing);
+                }
+            }
+        }
+
+        if (event != null) {
+            notifyDelegate(networkId, event);
+        }
+    }
+
+    @Override
+    public void removeGroupEntry(NetworkId networkId, Group group) {
+        StoredGroupEntry existing = null;
+        if (groupEntriesById.get(networkId) != null
+                && groupEntriesById.get(networkId).get(group.deviceId()) != null) {
+           existing = groupEntriesById
+                   .get(networkId).get(group.deviceId()).get(group.id());
+        }
+
+        if (existing != null) {
+            ConcurrentMap<GroupKey, StoredGroupEntry> keyTable =
+                    getGroupKeyTable(networkId, existing.deviceId());
+            ConcurrentMap<GroupId, StoredGroupEntry> idTable =
+                    getGroupIdTable(networkId, existing.deviceId());
+            idTable.remove(existing.id());
+            keyTable.remove(existing.appCookie());
+            notifyDelegate(networkId,
+                           new GroupEvent(GroupEvent.Type.GROUP_REMOVED, existing));
+        }
+    }
+
+    @Override
+    public void purgeGroupEntry(NetworkId networkId, DeviceId deviceId) {
+        if (groupEntriesById.get(networkId) != null) {
+            Set<Map.Entry<GroupId, StoredGroupEntry>> entryPendingRemove =
+                    groupEntriesById.get(networkId).get(deviceId).entrySet();
+            groupEntriesById.get(networkId).remove(deviceId);
+            groupEntriesByKey.get(networkId).remove(deviceId);
+
+            entryPendingRemove.forEach(entry -> {
+                notifyDelegate(networkId,
+                               new GroupEvent(GroupEvent.Type.GROUP_REMOVED,
+                                              entry.getValue()));
+            });
+        }
+    }
+
+    @Override
+    public void purgeGroupEntries(NetworkId networkId) {
+        if (groupEntriesById.get(networkId) != null) {
+            groupEntriesById.get((networkId)).values().forEach(groupEntries -> {
+                groupEntries.entrySet().forEach(entry -> {
+                    notifyDelegate(networkId,
+                                   new GroupEvent(GroupEvent.Type.GROUP_REMOVED,
+                                                  entry.getValue()));
+                });
+            });
+
+            groupEntriesById.get(networkId).clear();
+            groupEntriesByKey.get(networkId).clear();
+        }
+    }
+
+    @Override
+    public void addOrUpdateExtraneousGroupEntry(NetworkId networkId, Group group) {
+        ConcurrentMap<GroupId, Group> extraneousIdTable =
+                getExtraneousGroupIdTable(networkId, group.deviceId());
+        extraneousIdTable.put(group.id(), group);
+        // Check the reference counter
+        if (group.referenceCount() == 0) {
+            notifyDelegate(networkId,
+                           new GroupEvent(GroupEvent.Type.GROUP_REMOVE_REQUESTED, group));
+        }
+    }
+
+    @Override
+    public void removeExtraneousGroupEntry(NetworkId networkId, Group group) {
+        ConcurrentMap<GroupId, Group> extraneousIdTable =
+                getExtraneousGroupIdTable(networkId, group.deviceId());
+        extraneousIdTable.remove(group.id());
+    }
+
+    @Override
+    public Iterable<Group> getExtraneousGroups(NetworkId networkId, DeviceId deviceId) {
+        // flatten and make iterator unmodifiable
+        return FluentIterable.from(
+                getExtraneousGroupIdTable(networkId, deviceId).values());
+    }
+
+    @Override
+    public void deviceInitialAuditCompleted(NetworkId networkId, DeviceId deviceId,
+                                            boolean completed) {
+        deviceAuditStatus.computeIfAbsent(networkId, k -> new HashMap<>());
+
+        HashMap<DeviceId, Boolean> deviceAuditStatusByNetwork =
+                deviceAuditStatus.get(networkId);
+
+        synchronized (deviceAuditStatusByNetwork) {
+            if (completed) {
+                log.debug("deviceInitialAuditCompleted: AUDIT "
+                                  + "completed for device {}", deviceId);
+                deviceAuditStatusByNetwork.put(deviceId, true);
+                // Execute all pending group requests
+                ConcurrentMap<GroupKey, StoredGroupEntry> pendingGroupRequests =
+                        getPendingGroupKeyTable(networkId, deviceId);
+                for (Group group:pendingGroupRequests.values()) {
+                    GroupDescription tmp = new DefaultGroupDescription(
+                            group.deviceId(),
+                            group.type(),
+                            group.buckets(),
+                            group.appCookie(),
+                            group.givenGroupId(),
+                            group.appId());
+                    storeGroupDescriptionInternal(networkId, tmp);
+                }
+                getPendingGroupKeyTable(networkId, deviceId).clear();
+            } else {
+                if (deviceAuditStatusByNetwork.get(deviceId)) {
+                    log.debug("deviceInitialAuditCompleted: Clearing AUDIT "
+                                      + "status for device {}", deviceId);
+                    deviceAuditStatusByNetwork.put(deviceId, false);
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean deviceInitialAuditStatus(NetworkId networkId, DeviceId deviceId) {
+        deviceAuditStatus.computeIfAbsent(networkId, k -> new HashMap<>());
+
+        HashMap<DeviceId, Boolean> deviceAuditStatusByNetwork =
+                deviceAuditStatus.get(networkId);
+
+        synchronized (deviceAuditStatusByNetwork) {
+            return (deviceAuditStatusByNetwork.get(deviceId) != null)
+                    ? deviceAuditStatusByNetwork.get(deviceId) : false;
+        }
+    }
+
+    @Override
+    public void groupOperationFailed(NetworkId networkId, DeviceId deviceId,
+                                     GroupOperation operation) {
+
+        StoredGroupEntry existing = null;
+        if (groupEntriesById.get(networkId) != null &&
+                groupEntriesById.get(networkId).get(deviceId) != null) {
+            existing = groupEntriesById.get(networkId).get(deviceId)
+                    .get(operation.groupId());
+        }
+
+        if (existing == null) {
+            log.warn("No group entry with ID {} found ", operation.groupId());
+            return;
+        }
+
+        switch (operation.opType()) {
+            case ADD:
+                notifyDelegate(networkId,
+                               new GroupEvent(GroupEvent.Type.GROUP_ADD_FAILED,
+                                              existing));
+                break;
+            case MODIFY:
+                notifyDelegate(networkId,
+                               new GroupEvent(GroupEvent.Type.GROUP_UPDATE_FAILED,
+                                              existing));
+                break;
+            case DELETE:
+                notifyDelegate(networkId,
+                               new GroupEvent(GroupEvent.Type.GROUP_REMOVE_FAILED,
+                                              existing));
+                break;
+            default:
+                log.warn("Unknown group operation type {}", operation.opType());
+        }
+
+        ConcurrentMap<GroupKey, StoredGroupEntry> keyTable =
+                getGroupKeyTable(networkId, existing.deviceId());
+        ConcurrentMap<GroupId, StoredGroupEntry> idTable =
+                getGroupIdTable(networkId, existing.deviceId());
+        idTable.remove(existing.id());
+        keyTable.remove(existing.appCookie());
+    }
+
+    @Override
+    public void pushGroupMetrics(NetworkId networkId, DeviceId deviceId,
+                                 Collection<Group> groupEntries) {
+        boolean deviceInitialAuditStatus =
+                deviceInitialAuditStatus(networkId, deviceId);
+        Set<Group> southboundGroupEntries =
+                Sets.newHashSet(groupEntries);
+        Set<Group> storedGroupEntries =
+                Sets.newHashSet(getGroups(networkId, deviceId));
+        Set<Group> extraneousStoredEntries =
+                Sets.newHashSet(getExtraneousGroups(networkId, deviceId));
+
+        if (log.isTraceEnabled()) {
+            log.trace("pushGroupMetrics: Displaying all ({}) "
+                              + "southboundGroupEntries for device {}",
+                      southboundGroupEntries.size(),
+                      deviceId);
+            for (Group group : southboundGroupEntries) {
+                log.trace("Group {} in device {}", group, deviceId);
+            }
+
+            log.trace("Displaying all ({}) stored group entries for device {}",
+                      storedGroupEntries.size(),
+                      deviceId);
+            for (Group group : storedGroupEntries) {
+                log.trace("Stored Group {} for device {}", group, deviceId);
+            }
+        }
+
+        for (Iterator<Group> it2 = southboundGroupEntries.iterator(); it2.hasNext();) {
+            Group group = it2.next();
+            if (storedGroupEntries.remove(group)) {
+                // we both have the group, let's update some info then.
+                log.trace("Group AUDIT: group {} exists "
+                                  + "in both planes for device {}",
+                          group.id(), deviceId);
+                groupAdded(networkId, group);
+                it2.remove();
+            }
+        }
+        for (Group group : southboundGroupEntries) {
+            if (getGroup(networkId, group.deviceId(), group.id()) != null) {
+                // There is a group existing with the same id
+                // It is possible that group update is
+                // in progress while we got a stale info from switch
+                if (!storedGroupEntries.remove(getGroup(
+                        networkId, group.deviceId(), group.id()))) {
+                    log.warn("Group AUDIT: Inconsistent state:"
+                                     + "Group exists in ID based table while "
+                                     + "not present in key based table");
+                }
+            } else {
+                // there are groups in the switch that aren't in the store
+                log.trace("Group AUDIT: extraneous group {} exists "
+                                  + "in data plane for device {}",
+                          group.id(), deviceId);
+                extraneousStoredEntries.remove(group);
+                extraneousGroup(networkId, group);
+            }
+        }
+        for (Group group : storedGroupEntries) {
+            // there are groups in the store that aren't in the switch
+            log.trace("Group AUDIT: group {} missing "
+                              + "in data plane for device {}",
+                      group.id(), deviceId);
+            groupMissing(networkId, group);
+        }
+        for (Group group : extraneousStoredEntries) {
+            // there are groups in the extraneous store that
+            // aren't in the switch
+            log.trace("Group AUDIT: clearing extransoeus group {} "
+                              + "from store for device {}",
+                      group.id(), deviceId);
+            removeExtraneousGroupEntry(networkId, group);
+        }
+
+        if (!deviceInitialAuditStatus) {
+            log.debug("Group AUDIT: Setting device {} initial "
+                              + "AUDIT completed", deviceId);
+            deviceInitialAuditCompleted(networkId, deviceId, true);
+        }
+    }
+
+    @Override
+    public void notifyOfFailovers(NetworkId networkId, Collection<Group> failoverGroups) {
+        List<GroupEvent> failoverEvents = new ArrayList<>();
+        failoverGroups.forEach(group -> {
+            if (group.type() == Group.Type.FAILOVER) {
+                failoverEvents.add(new GroupEvent(GroupEvent.Type.GROUP_BUCKET_FAILOVER, group));
+            }
+        });
+        notifyDelegate(networkId, failoverEvents);
+    }
+
+    private void groupMissing(NetworkId networkId, Group group) {
+        switch (group.state()) {
+            case PENDING_DELETE:
+                log.debug("Group {} delete confirmation from device {} " +
+                                  "of virtaual network {}",
+                          group, group.deviceId(), networkId);
+                removeGroupEntry(networkId, group);
+                break;
+            case ADDED:
+            case PENDING_ADD:
+            case PENDING_UPDATE:
+                log.debug("Group {} is in store but not on device {}",
+                          group, group.deviceId());
+                StoredGroupEntry existing = null;
+                if (groupEntriesById.get(networkId) != null &&
+                        groupEntriesById.get(networkId).get(group.deviceId()) != null) {
+
+                    existing = groupEntriesById.get(networkId)
+                            .get(group.deviceId()).get(group.id());
+                }
+                if (existing == null) {
+                    break;
+                }
+
+                log.trace("groupMissing: group "
+                                  + "entry {} in device {} moving "
+                                  + "from {} to PENDING_ADD",
+                          existing.id(),
+                          existing.deviceId(),
+                          existing.state());
+                existing.setState(Group.GroupState.PENDING_ADD);
+                notifyDelegate(networkId, new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED,
+                                              group));
+                break;
+            default:
+                log.debug("Virtual network {} : Group {} has not been installed.",
+                          networkId, group);
+                break;
+        }
+    }
+
+    private void extraneousGroup(NetworkId networkId, Group group) {
+        log.debug("Group {} is on device {} of virtual network{}, but not in store.",
+                  group, group.deviceId(), networkId);
+        addOrUpdateExtraneousGroupEntry(networkId, group);
+    }
+
+    private void groupAdded(NetworkId networkId, Group group) {
+        log.trace("Group {} Added or Updated in device {} of virtual network {}",
+                  group, group.deviceId(), networkId);
+        addOrUpdateGroupEntry(networkId, group);
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualIntentStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualIntentStore.java
new file mode 100644
index 0000000..15b6bcd
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualIntentStore.java
@@ -0,0 +1,268 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntentStore;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.IntentStoreDelegate;
+import org.onosproject.net.intent.Key;
+import org.onosproject.store.Timestamp;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.intent.IntentState.PURGE_REQ;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Simple single-instance implementation of the intent store for virtual networks.
+ */
+
+@Component(immediate = true, service = VirtualNetworkIntentStore.class)
+public class SimpleVirtualIntentStore
+        extends AbstractVirtualStore<IntentEvent, IntentStoreDelegate>
+        implements VirtualNetworkIntentStore {
+
+    private final Logger log = getLogger(getClass());
+
+    private final Map<NetworkId, Map<Key, IntentData>> currentByNetwork =
+            Maps.newConcurrentMap();
+    private final Map<NetworkId, Map<Key, IntentData>> pendingByNetwork =
+            Maps.newConcurrentMap();
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+
+    @Override
+    public long getIntentCount(NetworkId networkId) {
+        return getCurrentMap(networkId).size();
+    }
+
+    @Override
+    public Iterable<Intent> getIntents(NetworkId networkId) {
+        return getCurrentMap(networkId).values().stream()
+                .map(IntentData::intent)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public Iterable<IntentData> getIntentData(NetworkId networkId,
+                                              boolean localOnly, long olderThan) {
+        if (localOnly || olderThan > 0) {
+            long older = System.nanoTime() - olderThan * 1_000_000; //convert ms to ns
+            final SystemClockTimestamp time = new SystemClockTimestamp(older);
+            return getCurrentMap(networkId).values().stream()
+                    .filter(data -> data.version().isOlderThan(time) &&
+                            (!localOnly || isMaster(networkId, data.key())))
+                    .collect(Collectors.toList());
+        }
+        return Lists.newArrayList(getCurrentMap(networkId).values());
+    }
+
+    @Override
+    public IntentState getIntentState(NetworkId networkId, Key intentKey) {
+        IntentData data = getCurrentMap(networkId).get(intentKey);
+        return (data != null) ? data.state() : null;
+    }
+
+    @Override
+    public List<Intent> getInstallableIntents(NetworkId networkId, Key intentKey) {
+        IntentData data = getCurrentMap(networkId).get(intentKey);
+        if (data != null) {
+            return data.installables();
+        }
+        return null;
+    }
+
+    @Override
+    public void write(NetworkId networkId, IntentData newData) {
+        checkNotNull(newData);
+
+        synchronized (this) {
+            // TODO this could be refactored/cleaned up
+            IntentData currentData = getCurrentMap(networkId).get(newData.key());
+            IntentData pendingData = getPendingMap(networkId).get(newData.key());
+
+            if (IntentData.isUpdateAcceptable(currentData, newData)) {
+                if (pendingData != null) {
+                    if (pendingData.state() == PURGE_REQ) {
+                        getCurrentMap(networkId).remove(newData.key(), newData);
+                    } else {
+                        getCurrentMap(networkId).put(newData.key(), IntentData.copy(newData));
+                    }
+
+                    if (pendingData.version().compareTo(newData.version()) <= 0) {
+                        // pendingData version is less than or equal to newData's
+                        // Note: a new update for this key could be pending (it's version will be greater)
+                        getPendingMap(networkId).remove(newData.key());
+                    }
+                }
+                IntentEvent.getEvent(newData).ifPresent(e -> notifyDelegate(networkId, e));
+            }
+        }
+    }
+
+    @Override
+    public void batchWrite(NetworkId networkId, Iterable<IntentData> updates) {
+        for (IntentData data : updates) {
+            write(networkId, data);
+        }
+    }
+
+    @Override
+    public Intent getIntent(NetworkId networkId, Key key) {
+        IntentData data = getCurrentMap(networkId).get(key);
+        return (data != null) ? data.intent() : null;
+    }
+
+    @Override
+    public IntentData getIntentData(NetworkId networkId, Key key) {
+        IntentData currentData = getCurrentMap(networkId).get(key);
+        if (currentData == null) {
+            return null;
+        }
+        return IntentData.copy(currentData);
+    }
+
+    @Override
+    public void addPending(NetworkId networkId, IntentData data) {
+        if (data.version() == null) { // recompiled intents will already have a version
+            data = new IntentData(data.intent(), data.state(), new SystemClockTimestamp());
+        }
+        synchronized (this) {
+            IntentData existingData = getPendingMap(networkId).get(data.key());
+            if (existingData == null ||
+                    // existing version is strictly less than data's version
+                    // Note: if they are equal, we already have the update
+                    // TODO maybe we should still make this <= to be safe?
+                    existingData.version().compareTo(data.version()) < 0) {
+                getPendingMap(networkId).put(data.key(), data);
+
+                checkNotNull(delegateMap.get(networkId), "Store delegate is not set")
+                        .process(IntentData.copy(data));
+                IntentEvent.getEvent(data).ifPresent(e -> notifyDelegate(networkId, e));
+            } else {
+                log.debug("IntentData {} is older than existing: {}",
+                          data, existingData);
+            }
+            //TODO consider also checking the current map at this point
+        }
+    }
+
+    @Override
+    public boolean isMaster(NetworkId networkId, Key intentKey) {
+        return true;
+    }
+
+    @Override
+    public Iterable<Intent> getPending(NetworkId networkId) {
+        return getPendingMap(networkId).values().stream()
+                .map(IntentData::intent)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public Iterable<IntentData> getPendingData(NetworkId networkId) {
+        return Lists.newArrayList(getPendingMap(networkId).values());
+    }
+
+    @Override
+    public IntentData getPendingData(NetworkId networkId, Key intentKey) {
+        return getPendingMap(networkId).get(intentKey);
+    }
+
+    @Override
+    public Iterable<IntentData> getPendingData(NetworkId networkId,
+                                               boolean localOnly, long olderThan) {
+        long older = System.nanoTime() - olderThan * 1_000_000; //convert ms to ns
+        final SystemClockTimestamp time = new SystemClockTimestamp(older);
+        return getPendingMap(networkId).values().stream()
+                .filter(data -> data.version().isOlderThan(time) &&
+                        (!localOnly || isMaster(networkId, data.key())))
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * Returns the current intent map for a specific virtual network.
+     *
+     * @param networkId a virtual network identifier
+     * @return the current map for the requested virtual network
+     */
+    private Map<Key, IntentData> getCurrentMap(NetworkId networkId) {
+        currentByNetwork.computeIfAbsent(networkId,
+                                   n -> Maps.newConcurrentMap());
+        return currentByNetwork.get(networkId);
+    }
+
+    /**
+     * Returns the pending intent map for a specific virtual network.
+     *
+     * @param networkId a virtual network identifier
+     * @return the pending intent map for the requested virtual network
+     */
+    private Map<Key, IntentData> getPendingMap(NetworkId networkId) {
+        pendingByNetwork.computeIfAbsent(networkId,
+                                   n -> Maps.newConcurrentMap());
+        return pendingByNetwork.get(networkId);
+    }
+
+    public class SystemClockTimestamp implements Timestamp {
+
+        private final long nanoTimestamp;
+
+        public SystemClockTimestamp() {
+            nanoTimestamp = System.nanoTime();
+        }
+
+        public SystemClockTimestamp(long timestamp) {
+            nanoTimestamp = timestamp;
+        }
+
+        @Override
+        public int compareTo(Timestamp o) {
+            checkArgument(o instanceof SystemClockTimestamp,
+                          "Must be SystemClockTimestamp", o);
+            SystemClockTimestamp that = (SystemClockTimestamp) o;
+
+            return ComparisonChain.start()
+                    .compare(this.nanoTimestamp, that.nanoTimestamp)
+                    .result();
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMastershipStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMastershipStore.java
new file mode 100644
index 0000000..68d8ed8
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMastershipStore.java
@@ -0,0 +1,538 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.IpAddress;
+import org.onosproject.cluster.ClusterEventListener;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.DefaultControllerNode;
+import org.onosproject.cluster.Node;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.cluster.RoleInfo;
+import org.onosproject.core.Version;
+import org.onosproject.core.VersionService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkMastershipStore;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipInfo;
+import org.onosproject.mastership.MastershipStoreDelegate;
+import org.onosproject.mastership.MastershipTerm;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.onosproject.mastership.MastershipEvent.Type.BACKUPS_CHANGED;
+import static org.onosproject.mastership.MastershipEvent.Type.MASTER_CHANGED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of the virtual network mastership store to manage inventory of
+ * mastership using trivial in-memory implementation.
+ */
+@Component(immediate = true, service = VirtualNetworkMastershipStore.class)
+public class SimpleVirtualMastershipStore
+        extends AbstractVirtualStore<MastershipEvent, MastershipStoreDelegate>
+        implements VirtualNetworkMastershipStore {
+
+    private final Logger log = getLogger(getClass());
+
+    private static final int NOTHING = 0;
+    private static final int INIT = 1;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected VersionService versionService;
+
+    //devices mapped to their masters, to emulate multiple nodes
+    protected final Map<NetworkId, Map<DeviceId, NodeId>> masterMapByNetwork =
+            new HashMap<>();
+    //emulate backups with pile of nodes
+    protected final Map<NetworkId, Map<DeviceId, List<NodeId>>> backupsByNetwork =
+            new HashMap<>();
+    //terms
+    protected final Map<NetworkId, Map<DeviceId, AtomicInteger>> termMapByNetwork =
+            new HashMap<>();
+
+    @Activate
+    public void activate() {
+        if (clusterService == null) {
+            clusterService = createFakeClusterService();
+        }
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    @Override
+    public CompletableFuture<MastershipRole> requestRole(NetworkId networkId,
+                                                         DeviceId deviceId) {
+        //query+possible reelection
+        NodeId node = clusterService.getLocalNode().id();
+        MastershipRole role = getRole(networkId, node, deviceId);
+
+        Map<DeviceId, NodeId> masterMap = getMasterMap(networkId);
+
+        switch (role) {
+            case MASTER:
+                return CompletableFuture.completedFuture(MastershipRole.MASTER);
+            case STANDBY:
+                if (getMaster(networkId, deviceId) == null) {
+                    // no master => become master
+                    masterMap.put(deviceId, node);
+                    incrementTerm(networkId, deviceId);
+                    // remove from backup list
+                    removeFromBackups(networkId, deviceId, node);
+                    notifyDelegate(networkId, new MastershipEvent(MASTER_CHANGED, deviceId,
+                        getMastership(networkId, deviceId)));
+                    return CompletableFuture.completedFuture(MastershipRole.MASTER);
+                }
+                return CompletableFuture.completedFuture(MastershipRole.STANDBY);
+            case NONE:
+                if (getMaster(networkId, deviceId) == null) {
+                    // no master => become master
+                    masterMap.put(deviceId, node);
+                    incrementTerm(networkId, deviceId);
+                    notifyDelegate(networkId, new MastershipEvent(MASTER_CHANGED, deviceId,
+                        getMastership(networkId, deviceId)));
+                    return CompletableFuture.completedFuture(MastershipRole.MASTER);
+                }
+                // add to backup list
+                if (addToBackup(networkId, deviceId, node)) {
+                    notifyDelegate(networkId, new MastershipEvent(BACKUPS_CHANGED, deviceId,
+                        getMastership(networkId, deviceId)));
+                }
+                return CompletableFuture.completedFuture(MastershipRole.STANDBY);
+            default:
+                log.warn("unknown Mastership Role {}", role);
+        }
+        return CompletableFuture.completedFuture(role);
+    }
+
+    @Override
+    public MastershipRole getRole(NetworkId networkId, NodeId nodeId, DeviceId deviceId) {
+        Map<DeviceId, NodeId> masterMap = getMasterMap(networkId);
+        Map<DeviceId, List<NodeId>> backups = getBackups(networkId);
+
+        //just query
+        NodeId current = masterMap.get(deviceId);
+        MastershipRole role;
+
+        if (current != null && current.equals(nodeId)) {
+            return MastershipRole.MASTER;
+        }
+
+        if (backups.getOrDefault(deviceId, Collections.emptyList()).contains(nodeId)) {
+            role = MastershipRole.STANDBY;
+        } else {
+            role = MastershipRole.NONE;
+        }
+        return role;
+    }
+
+    @Override
+    public NodeId getMaster(NetworkId networkId, DeviceId deviceId) {
+        Map<DeviceId, NodeId> masterMap = getMasterMap(networkId);
+        return masterMap.get(deviceId);
+    }
+
+    @Override
+    public RoleInfo getNodes(NetworkId networkId, DeviceId deviceId) {
+        Map<DeviceId, NodeId> masterMap = getMasterMap(networkId);
+        Map<DeviceId, List<NodeId>> backups = getBackups(networkId);
+
+        return new RoleInfo(masterMap.get(deviceId),
+                            backups.getOrDefault(deviceId, ImmutableList.of()));
+    }
+
+    @Override
+    public MastershipInfo getMastership(NetworkId networkId, DeviceId deviceId) {
+        Map<DeviceId, NodeId> masterMap = getMasterMap(networkId);
+        Map<DeviceId, AtomicInteger> termMap = getTermMap(networkId);
+        Map<DeviceId, List<NodeId>> backups = getBackups(networkId);
+        ImmutableMap.Builder<NodeId, MastershipRole> roleBuilder = ImmutableMap.builder();
+        NodeId master = masterMap.get(deviceId);
+        if (master != null) {
+            roleBuilder.put(master, MastershipRole.MASTER);
+        }
+        backups.getOrDefault(deviceId, Collections.emptyList())
+            .forEach(nodeId -> roleBuilder.put(nodeId, MastershipRole.STANDBY));
+        clusterService.getNodes().stream()
+            .filter(node -> !masterMap.containsValue(node.id()))
+            .filter(node -> !backups.get(deviceId).contains(node.id()))
+            .forEach(node -> roleBuilder.put(node.id(), MastershipRole.NONE));
+        return new MastershipInfo(
+            termMap.getOrDefault(deviceId, new AtomicInteger(NOTHING)).get(),
+            Optional.ofNullable(master),
+            roleBuilder.build());
+    }
+
+    @Override
+    public Set<DeviceId> getDevices(NetworkId networkId, NodeId nodeId) {
+        Map<DeviceId, NodeId> masterMap = getMasterMap(networkId);
+
+        Set<DeviceId> ids = new HashSet<>();
+        for (Map.Entry<DeviceId, NodeId> d : masterMap.entrySet()) {
+            if (Objects.equals(d.getValue(), nodeId)) {
+                ids.add(d.getKey());
+            }
+        }
+        return ids;
+    }
+
+    @Override
+    public synchronized CompletableFuture<MastershipEvent> setMaster(NetworkId networkId,
+                                                        NodeId nodeId, DeviceId deviceId) {
+        Map<DeviceId, NodeId> masterMap = getMasterMap(networkId);
+
+        MastershipRole role = getRole(networkId, nodeId, deviceId);
+        switch (role) {
+            case MASTER:
+                // no-op
+                return CompletableFuture.completedFuture(null);
+            case STANDBY:
+            case NONE:
+                NodeId prevMaster = masterMap.put(deviceId, nodeId);
+                incrementTerm(networkId, deviceId);
+                removeFromBackups(networkId, deviceId, nodeId);
+                addToBackup(networkId, deviceId, prevMaster);
+                break;
+            default:
+                log.warn("unknown Mastership Role {}", role);
+                return null;
+        }
+
+        return CompletableFuture.completedFuture(
+                new MastershipEvent(MASTER_CHANGED, deviceId, getMastership(networkId, deviceId)));
+    }
+
+    @Override
+    public MastershipTerm getTermFor(NetworkId networkId, DeviceId deviceId) {
+        Map<DeviceId, NodeId> masterMap = getMasterMap(networkId);
+        Map<DeviceId, AtomicInteger> termMap = getTermMap(networkId);
+
+        if ((termMap.get(deviceId) == null)) {
+            return MastershipTerm.of(masterMap.get(deviceId), NOTHING);
+        }
+        return MastershipTerm.of(
+                masterMap.get(deviceId), termMap.get(deviceId).get());
+    }
+
+    @Override
+    public CompletableFuture<MastershipEvent> setStandby(NetworkId networkId,
+                                                         NodeId nodeId, DeviceId deviceId) {
+        Map<DeviceId, NodeId> masterMap = getMasterMap(networkId);
+
+        MastershipRole role = getRole(networkId, nodeId, deviceId);
+        switch (role) {
+            case MASTER:
+                NodeId backup = reelect(networkId, deviceId, nodeId);
+                if (backup == null) {
+                    // no master alternative
+                    masterMap.remove(deviceId);
+                    // TODO: Should there be new event type for no MASTER?
+                    return CompletableFuture.completedFuture(
+                            new MastershipEvent(MASTER_CHANGED, deviceId,
+                                getMastership(networkId, deviceId)));
+                } else {
+                    NodeId prevMaster = masterMap.put(deviceId, backup);
+                    incrementTerm(networkId, deviceId);
+                    addToBackup(networkId, deviceId, prevMaster);
+                    return CompletableFuture.completedFuture(
+                            new MastershipEvent(MASTER_CHANGED, deviceId,
+                                getMastership(networkId, deviceId)));
+                }
+
+            case STANDBY:
+            case NONE:
+                boolean modified = addToBackup(networkId, deviceId, nodeId);
+                if (modified) {
+                    return CompletableFuture.completedFuture(
+                            new MastershipEvent(BACKUPS_CHANGED, deviceId,
+                                getMastership(networkId, deviceId)));
+                }
+                break;
+
+            default:
+                log.warn("unknown Mastership Role {}", role);
+        }
+        return null;
+    }
+
+
+    /**
+     * Dumbly selects next-available node that's not the current one.
+     * emulate leader election.
+     *
+     * @param networkId a virtual network identifier
+     * @param deviceId a virtual device identifier
+     * @param nodeId a nod identifier
+     * @return Next available node as a leader
+     */
+    private synchronized NodeId reelect(NetworkId networkId, DeviceId deviceId,
+                                        NodeId nodeId) {
+        Map<DeviceId, List<NodeId>> backups = getBackups(networkId);
+
+        List<NodeId> stbys = backups.getOrDefault(deviceId, Collections.emptyList());
+        NodeId backup = null;
+        for (NodeId n : stbys) {
+            if (!n.equals(nodeId)) {
+                backup = n;
+                break;
+            }
+        }
+        stbys.remove(backup);
+        return backup;
+    }
+
+    @Override
+    public synchronized CompletableFuture<MastershipEvent>
+    relinquishRole(NetworkId networkId, NodeId nodeId, DeviceId deviceId) {
+    Map<DeviceId, NodeId> masterMap = getMasterMap(networkId);
+
+        MastershipRole role = getRole(networkId, nodeId, deviceId);
+        switch (role) {
+            case MASTER:
+                NodeId backup = reelect(networkId, deviceId, nodeId);
+                masterMap.put(deviceId, backup);
+                incrementTerm(networkId, deviceId);
+                return CompletableFuture.completedFuture(
+                        new MastershipEvent(MASTER_CHANGED, deviceId,
+                            getMastership(networkId, deviceId)));
+
+            case STANDBY:
+                if (removeFromBackups(networkId, deviceId, nodeId)) {
+                    return CompletableFuture.completedFuture(
+                            new MastershipEvent(BACKUPS_CHANGED, deviceId,
+                                getMastership(networkId, deviceId)));
+                }
+                break;
+
+            case NONE:
+                break;
+
+            default:
+                log.warn("unknown Mastership Role {}", role);
+        }
+        return CompletableFuture.completedFuture(null);
+    }
+
+    @Override
+    public void relinquishAllRole(NetworkId networkId, NodeId nodeId) {
+        Map<DeviceId, NodeId> masterMap = getMasterMap(networkId);
+        Map<DeviceId, List<NodeId>> backups = getBackups(networkId);
+
+        List<CompletableFuture<MastershipEvent>> eventFutures = new ArrayList<>();
+        Set<DeviceId> toRelinquish = new HashSet<>();
+
+        masterMap.entrySet().stream()
+                .filter(entry -> nodeId.equals(entry.getValue()))
+                .forEach(entry -> toRelinquish.add(entry.getKey()));
+
+        backups.entrySet().stream()
+                .filter(entry -> entry.getValue().contains(nodeId))
+                .forEach(entry -> toRelinquish.add(entry.getKey()));
+
+        toRelinquish.forEach(deviceId -> eventFutures.add(
+                relinquishRole(networkId, nodeId, deviceId)));
+
+        eventFutures.forEach(future -> {
+            future.whenComplete((event, error) -> notifyDelegate(networkId, event));
+        });
+    }
+
+    /**
+     * Increase the term for a device, and store it.
+     *
+     * @param networkId a virtual network identifier
+     * @param deviceId a virtual device identifier
+     */
+    private synchronized void incrementTerm(NetworkId networkId, DeviceId deviceId) {
+        Map<DeviceId, AtomicInteger> termMap = getTermMap(networkId);
+
+        AtomicInteger term = termMap.getOrDefault(deviceId, new AtomicInteger(NOTHING));
+        term.incrementAndGet();
+        termMap.put(deviceId, term);
+    }
+
+    /**
+     * Remove backup node for a device.
+     *
+     * @param networkId a virtual network identifier
+     * @param deviceId a virtual device identifier
+     * @param nodeId a node identifier
+     * @return True if success
+     */
+    private synchronized boolean removeFromBackups(NetworkId networkId,
+                                                   DeviceId deviceId, NodeId nodeId) {
+        Map<DeviceId, List<NodeId>> backups = getBackups(networkId);
+
+        List<NodeId> stbys = backups.getOrDefault(deviceId, new ArrayList<>());
+        boolean modified = stbys.remove(nodeId);
+        backups.put(deviceId, stbys);
+        return modified;
+    }
+
+    /**
+     * add to backup if not there already, silently ignores null node.
+     *
+     * @param networkId a virtual network identifier
+     * @param deviceId a virtual device identifier
+     * @param nodeId a node identifier
+     * @return True if success
+     */
+    private synchronized boolean addToBackup(NetworkId networkId,
+                                             DeviceId deviceId, NodeId nodeId) {
+        Map<DeviceId, List<NodeId>> backups = getBackups(networkId);
+
+        boolean modified = false;
+        List<NodeId> stbys = backups.getOrDefault(deviceId, new ArrayList<>());
+        if (nodeId != null && !stbys.contains(nodeId)) {
+            stbys.add(nodeId);
+            backups.put(deviceId, stbys);
+            modified = true;
+        }
+        return modified;
+    }
+
+    /**
+     * Returns deviceId-master map for a specified virtual network.
+     *
+     * @param networkId a virtual network identifier
+     * @return DeviceId-master map of a given virtual network.
+     */
+    private Map<DeviceId, NodeId> getMasterMap(NetworkId networkId) {
+        return masterMapByNetwork.computeIfAbsent(networkId, k -> new HashMap<>());
+    }
+
+    /**
+     * Returns deviceId-backups map for a specified virtual network.
+     *
+     * @param networkId a virtual network identifier
+     * @return DeviceId-backups map of a given virtual network.
+     */
+    private Map<DeviceId, List<NodeId>> getBackups(NetworkId networkId) {
+        return backupsByNetwork.computeIfAbsent(networkId, k -> new HashMap<>());
+    }
+
+    /**
+     * Returns deviceId-terms map for a specified virtual network.
+     *
+     * @param networkId a virtual network identifier
+     * @return DeviceId-terms map of a given virtual network.
+     */
+    private Map<DeviceId, AtomicInteger> getTermMap(NetworkId networkId) {
+        return termMapByNetwork.computeIfAbsent(networkId, k -> new HashMap<>());
+    }
+
+    /**
+     * Returns a fake cluster service for a test purpose only.
+     *
+     * @return a fake cluster service
+     */
+    private ClusterService createFakeClusterService() {
+        // just for ease of unit test
+        final ControllerNode instance =
+                new DefaultControllerNode(new NodeId("local"),
+                                          IpAddress.valueOf("127.0.0.1"));
+
+        ClusterService faceClusterService = new ClusterService() {
+
+            private final Instant creationTime = Instant.now();
+
+            @Override
+            public ControllerNode getLocalNode() {
+                return instance;
+            }
+
+            @Override
+            public Set<ControllerNode> getNodes() {
+                return ImmutableSet.of(instance);
+            }
+
+            @Override
+            public Set<Node> getConsensusNodes() {
+                return ImmutableSet.of();
+            }
+
+            @Override
+            public ControllerNode getNode(NodeId nodeId) {
+                if (instance.id().equals(nodeId)) {
+                    return instance;
+                }
+                return null;
+            }
+
+            @Override
+            public ControllerNode.State getState(NodeId nodeId) {
+                if (instance.id().equals(nodeId)) {
+                    return ControllerNode.State.ACTIVE;
+                } else {
+                    return ControllerNode.State.INACTIVE;
+                }
+            }
+
+            @Override
+            public Version getVersion(NodeId nodeId) {
+                if (instance.id().equals(nodeId)) {
+                    return versionService.version();
+                }
+                return null;
+            }
+
+            @Override
+            public Instant getLastUpdatedInstant(NodeId nodeId) {
+                return creationTime;
+            }
+
+            @Override
+            public void addListener(ClusterEventListener listener) {
+            }
+
+            @Override
+            public void removeListener(ClusterEventListener listener) {
+            }
+        };
+        return faceClusterService;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMeterStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMeterStore.java
new file mode 100644
index 0000000..5add89d
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMeterStore.java
@@ -0,0 +1,265 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Maps;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkMeterStore;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.DefaultMeter;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterEvent;
+import org.onosproject.net.meter.MeterFailReason;
+import org.onosproject.net.meter.MeterFeatures;
+import org.onosproject.net.meter.MeterFeaturesKey;
+import org.onosproject.net.meter.MeterKey;
+import org.onosproject.net.meter.MeterOperation;
+import org.onosproject.net.meter.MeterStoreDelegate;
+import org.onosproject.net.meter.MeterStoreResult;
+import org.onosproject.store.service.StorageException;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static org.onosproject.net.meter.MeterFailReason.TIMEOUT;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of the virtual meter store for a single instance.
+ */
+//TODO: support distributed meter store for virtual networks
+@Component(immediate = true, service = VirtualNetworkMeterStore.class)
+public class SimpleVirtualMeterStore
+        extends AbstractVirtualStore<MeterEvent, MeterStoreDelegate>
+        implements VirtualNetworkMeterStore {
+
+        private Logger log = getLogger(getClass());
+
+        @Reference(cardinality = ReferenceCardinality.MANDATORY)
+        protected ClusterService clusterService;
+
+        private ConcurrentMap<NetworkId, ConcurrentMap<MeterKey, MeterData>> meterMap =
+                Maps.newConcurrentMap();
+
+        private NodeId local;
+
+        private ConcurrentMap<NetworkId, ConcurrentMap<MeterFeaturesKey, MeterFeatures>>
+                meterFeatureMap = Maps.newConcurrentMap();
+
+        private ConcurrentMap<NetworkId,
+                ConcurrentMap<MeterKey, CompletableFuture<MeterStoreResult>>> futuresMap =
+                Maps.newConcurrentMap();
+
+        @Activate
+        public void activate() {
+            log.info("Started");
+            local = clusterService.getLocalNode().id();
+        }
+
+        @Deactivate
+        public void deactivate() {
+            log.info("Stopped");
+        }
+
+        private ConcurrentMap<MeterKey, MeterData> getMetersByNetwork(NetworkId networkId) {
+            meterMap.computeIfAbsent(networkId, m -> new ConcurrentHashMap<>());
+            return meterMap.get(networkId);
+        }
+
+        private ConcurrentMap<MeterFeaturesKey, MeterFeatures>
+        getMeterFeaturesByNetwork(NetworkId networkId) {
+            meterFeatureMap.computeIfAbsent(networkId, f -> new ConcurrentHashMap<>());
+            return meterFeatureMap.get(networkId);
+        }
+
+        private ConcurrentMap<MeterKey, CompletableFuture<MeterStoreResult>>
+        getFuturesByNetwork(NetworkId networkId) {
+            futuresMap.computeIfAbsent(networkId, f -> new ConcurrentHashMap<>());
+            return futuresMap.get(networkId);
+        }
+
+        @Override
+        public CompletableFuture<MeterStoreResult> storeMeter(NetworkId networkId, Meter meter) {
+
+            ConcurrentMap<MeterKey, MeterData> meters = getMetersByNetwork(networkId);
+
+            ConcurrentMap<MeterKey, CompletableFuture<MeterStoreResult>> futures =
+                   getFuturesByNetwork(networkId);
+
+            CompletableFuture<MeterStoreResult> future = new CompletableFuture<>();
+            MeterKey key = MeterKey.key(meter.deviceId(), meter.id());
+            futures.put(key, future);
+            MeterData data = new MeterData(meter, null, local);
+
+            try {
+                    meters.put(key, data);
+            } catch (StorageException e) {
+                    future.completeExceptionally(e);
+            }
+
+            return future;
+        }
+
+        @Override
+        public CompletableFuture<MeterStoreResult> deleteMeter(NetworkId networkId, Meter meter) {
+            ConcurrentMap<MeterKey, MeterData> meters = getMetersByNetwork(networkId);
+
+            ConcurrentMap<MeterKey, CompletableFuture<MeterStoreResult>> futures =
+                    getFuturesByNetwork(networkId);
+
+            CompletableFuture<MeterStoreResult> future = new CompletableFuture<>();
+            MeterKey key = MeterKey.key(meter.deviceId(), meter.id());
+            futures.put(key, future);
+
+            MeterData data = new MeterData(meter, null, local);
+
+            // update the state of the meter. It will be pruned by observing
+            // that it has been removed from the dataplane.
+            try {
+                    if (meters.computeIfPresent(key, (k, v) -> data) == null) {
+                            future.complete(MeterStoreResult.success());
+                    }
+            } catch (StorageException e) {
+                    future.completeExceptionally(e);
+            }
+
+            return future;
+        }
+
+        @Override
+        public MeterStoreResult storeMeterFeatures(NetworkId networkId, MeterFeatures meterfeatures) {
+            ConcurrentMap<MeterFeaturesKey, MeterFeatures> meterFeatures
+                    = getMeterFeaturesByNetwork(networkId);
+
+            MeterStoreResult result = MeterStoreResult.success();
+            MeterFeaturesKey key = MeterFeaturesKey.key(meterfeatures.deviceId());
+            try {
+                    meterFeatures.putIfAbsent(key, meterfeatures);
+            } catch (StorageException e) {
+                    result = MeterStoreResult.fail(TIMEOUT);
+            }
+            return result;
+        }
+
+        @Override
+        public MeterStoreResult deleteMeterFeatures(NetworkId networkId, DeviceId deviceId) {
+            ConcurrentMap<MeterFeaturesKey, MeterFeatures> meterFeatures
+                    = getMeterFeaturesByNetwork(networkId);
+
+            MeterStoreResult result = MeterStoreResult.success();
+            MeterFeaturesKey key = MeterFeaturesKey.key(deviceId);
+            try {
+                    meterFeatures.remove(key);
+            } catch (StorageException e) {
+                    result = MeterStoreResult.fail(TIMEOUT);
+            }
+            return result;
+        }
+
+        @Override
+        public CompletableFuture<MeterStoreResult> updateMeter(NetworkId networkId, Meter meter) {
+            ConcurrentMap<MeterKey, MeterData> meters = getMetersByNetwork(networkId);
+            ConcurrentMap<MeterKey, CompletableFuture<MeterStoreResult>> futures =
+                    getFuturesByNetwork(networkId);
+
+            CompletableFuture<MeterStoreResult> future = new CompletableFuture<>();
+            MeterKey key = MeterKey.key(meter.deviceId(), meter.id());
+            futures.put(key, future);
+
+            MeterData data = new MeterData(meter, null, local);
+            try {
+                    if (meters.computeIfPresent(key, (k, v) -> data) == null) {
+                            future.complete(MeterStoreResult.fail(MeterFailReason.INVALID_METER));
+                    }
+            } catch (StorageException e) {
+                    future.completeExceptionally(e);
+            }
+            return future;
+        }
+
+        @Override
+        public void updateMeterState(NetworkId networkId, Meter meter) {
+            ConcurrentMap<MeterKey, MeterData> meters = getMetersByNetwork(networkId);
+
+            MeterKey key = MeterKey.key(meter.deviceId(), meter.id());
+            meters.computeIfPresent(key, (k, v) -> {
+                    DefaultMeter m = (DefaultMeter) v.meter();
+                    m.setState(meter.state());
+                    m.setProcessedPackets(meter.packetsSeen());
+                    m.setProcessedBytes(meter.bytesSeen());
+                    m.setLife(meter.life());
+                    // TODO: Prune if drops to zero.
+                    m.setReferenceCount(meter.referenceCount());
+                    return new MeterData(m, null, v.origin());
+            });
+        }
+
+        @Override
+        public Meter getMeter(NetworkId networkId, MeterKey key) {
+            ConcurrentMap<MeterKey, MeterData> meters = getMetersByNetwork(networkId);
+
+            MeterData data = meters.get(key);
+            return data == null ? null : data.meter();
+        }
+
+        @Override
+        public Collection<Meter> getAllMeters(NetworkId networkId) {
+            ConcurrentMap<MeterKey, MeterData> meters = getMetersByNetwork(networkId);
+
+            return Collections2.transform(meters.values(), MeterData::meter);
+        }
+
+        @Override
+        public void failedMeter(NetworkId networkId, MeterOperation op, MeterFailReason reason) {
+            ConcurrentMap<MeterKey, MeterData> meters = getMetersByNetwork(networkId);
+
+            MeterKey key = MeterKey.key(op.meter().deviceId(), op.meter().id());
+            meters.computeIfPresent(key, (k, v) ->
+                    new MeterData(v.meter(), reason, v.origin()));
+        }
+
+        @Override
+        public void deleteMeterNow(NetworkId networkId, Meter m) {
+            ConcurrentMap<MeterKey, MeterData> meters = getMetersByNetwork(networkId);
+            ConcurrentMap<MeterKey, CompletableFuture<MeterStoreResult>> futures =
+                    getFuturesByNetwork(networkId);
+
+            MeterKey key = MeterKey.key(m.deviceId(), m.id());
+            futures.remove(key);
+            meters.remove(key);
+        }
+
+        @Override
+        public long getMaxMeters(NetworkId networkId, MeterFeaturesKey key) {
+            ConcurrentMap<MeterFeaturesKey, MeterFeatures> meterFeatures
+                    = getMeterFeaturesByNetwork(networkId);
+
+            MeterFeatures features = meterFeatures.get(key);
+            return features == null ? 0L : features.maxMeter();
+        }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualPacketStore.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualPacketStore.java
new file mode 100644
index 0000000..e0bb7c6
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualPacketStore.java
@@ -0,0 +1,125 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkPacketStore;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketEvent;
+import org.onosproject.net.packet.PacketRequest;
+import org.onosproject.net.packet.PacketStoreDelegate;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.slf4j.Logger;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Simple single instance implementation of the virtual packet store.
+ */
+//TODO: support distributed packet store for virtual networks
+
+@Component(immediate = true, service = VirtualNetworkPacketStore.class)
+public class SimpleVirtualPacketStore
+        extends AbstractVirtualStore<PacketEvent, PacketStoreDelegate>
+        implements VirtualNetworkPacketStore {
+
+    private final Logger log = getLogger(getClass());
+
+    private Map<NetworkId, Map<TrafficSelector, Set<PacketRequest>>> requests
+            = Maps.newConcurrentMap();
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    @Override
+    public void emit(NetworkId networkId, OutboundPacket packet) {
+        notifyDelegate(networkId, new PacketEvent(PacketEvent.Type.EMIT, packet));
+    }
+
+    @Override
+    public void requestPackets(NetworkId networkId, PacketRequest request) {
+        requests.computeIfAbsent(networkId, k -> Maps.newConcurrentMap());
+
+        requests.get(networkId).compute(request.selector(), (s, existingRequests) -> {
+            if (existingRequests == null) {
+                if (hasDelegate(networkId)) {
+                    delegateMap.get(networkId).requestPackets(request);
+                }
+                return ImmutableSet.of(request);
+            } else if (!existingRequests.contains(request)) {
+                if (hasDelegate(networkId)) {
+                    delegateMap.get(networkId).requestPackets(request);
+                }
+                return ImmutableSet.<PacketRequest>builder()
+                        .addAll(existingRequests)
+                        .add(request)
+                        .build();
+            } else {
+                return existingRequests;
+            }
+        });
+    }
+
+    @Override
+    public void cancelPackets(NetworkId networkId, PacketRequest request) {
+        requests.get(networkId).computeIfPresent(request.selector(), (s, existingRequests) -> {
+            if (existingRequests.contains(request)) {
+                HashSet<PacketRequest> newRequests = Sets.newHashSet(existingRequests);
+                newRequests.remove(request);
+                if (hasDelegate(networkId)) {
+                    delegateMap.get(networkId).cancelPackets(request);
+                }
+                if (newRequests.size() > 0) {
+                    return ImmutableSet.copyOf(newRequests);
+                } else {
+                    return null;
+                }
+            } else {
+                return existingRequests;
+            }
+        });
+    }
+
+    @Override
+    public List<PacketRequest> existingRequests(NetworkId networkId) {
+        List<PacketRequest> list = Lists.newArrayList();
+        if (requests.get(networkId) != null) {
+            requests.get(networkId).values().forEach(list::addAll);
+            list.sort((o1, o2) -> o1.priority().priorityValue() - o2.priority().priorityValue());
+        }
+        return list;
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/package-info.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/package-info.java
new file mode 100644
index 0000000..99b5d82
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Implementation of virtual network stores.
+ */
+package org.onosproject.incubator.net.virtual.store.impl;
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualDeviceId.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualDeviceId.java
new file mode 100644
index 0000000..6a38661
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualDeviceId.java
@@ -0,0 +1,64 @@
+/*
+ * 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.store.impl.primitives;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.DeviceId;
+
+import java.util.Objects;
+
+/**
+ * A wrapper class to isolate device id from other virtual networks.
+ */
+public class VirtualDeviceId {
+
+    NetworkId networkId;
+    DeviceId deviceId;
+
+    public VirtualDeviceId(NetworkId networkId, DeviceId deviceId) {
+        this.networkId = networkId;
+        this.deviceId = deviceId;
+    }
+
+    public NetworkId networkId() {
+        return networkId;
+    }
+
+    public DeviceId deviceId() {
+        return deviceId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(networkId, deviceId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof VirtualDeviceId) {
+            VirtualDeviceId that = (VirtualDeviceId) obj;
+            return this.deviceId.equals(that.deviceId) &&
+                    this.networkId.equals(that.networkId);
+        }
+        return false;
+    }
+}
+
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowEntry.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowEntry.java
new file mode 100644
index 0000000..2a00883
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowEntry.java
@@ -0,0 +1,63 @@
+/*
+ * 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.store.impl.primitives;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.flow.FlowEntry;
+
+import java.util.Objects;
+
+/**
+ * A wrapper class to encapsulate flow entry.
+ */
+public class VirtualFlowEntry {
+    NetworkId networkId;
+    FlowEntry flowEntry;
+
+    public VirtualFlowEntry(NetworkId networkId, FlowEntry flowEntry) {
+        this.networkId = networkId;
+        this.flowEntry = flowEntry;
+    }
+
+    public NetworkId networkId() {
+        return networkId;
+    }
+
+    public FlowEntry flowEntry() {
+        return flowEntry;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(networkId, flowEntry);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+
+        if (other instanceof VirtualFlowEntry) {
+            VirtualFlowEntry that = (VirtualFlowEntry) other;
+            return this.networkId.equals(that.networkId) &&
+                    this.flowEntry.equals(that.flowEntry);
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowRule.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowRule.java
new file mode 100644
index 0000000..ea64904
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowRule.java
@@ -0,0 +1,65 @@
+/*
+ * 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.store.impl.primitives;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.flow.FlowRule;
+
+import java.util.Objects;
+
+/**
+ * A wrapper class to encapsulate flow rule.
+ */
+public class VirtualFlowRule {
+    NetworkId networkId;
+    FlowRule rule;
+
+    public VirtualFlowRule(NetworkId networkId, FlowRule rule) {
+        this.networkId = networkId;
+        this.rule = rule;
+    }
+
+    public NetworkId networkId() {
+        return networkId;
+    }
+
+    public FlowRule rule() {
+        return rule;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(networkId, rule);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this ==  other) {
+            return true;
+        }
+
+        if (other instanceof VirtualFlowRule) {
+            VirtualFlowRule that = (VirtualFlowRule) other;
+            return this.networkId.equals(that.networkId) &&
+                    this.rule.equals(that.rule);
+        } else {
+            return false;
+        }
+    }
+}
+
+
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowRuleBatchEvent.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowRuleBatchEvent.java
new file mode 100644
index 0000000..d1b5d57
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowRuleBatchEvent.java
@@ -0,0 +1,65 @@
+/*
+ * 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.store.impl.primitives;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchEvent;
+
+import java.util.Objects;
+
+/**
+ * A wrapper class to encapsulate flow rule batch event.
+ */
+public class VirtualFlowRuleBatchEvent {
+    NetworkId networkId;
+    FlowRuleBatchEvent event;
+
+    public VirtualFlowRuleBatchEvent(NetworkId networkId, FlowRuleBatchEvent event) {
+        this.networkId = networkId;
+        this.event = event;
+    }
+
+    public NetworkId networkId() {
+        return networkId;
+    }
+
+    public FlowRuleBatchEvent event() {
+        return event;
+    }
+
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(networkId, event);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+
+        if (other instanceof VirtualFlowRuleBatchEvent) {
+            VirtualFlowRuleBatchEvent that = (VirtualFlowRuleBatchEvent) other;
+            return this.networkId.equals(that.networkId) &&
+                    this.event.equals(that.event);
+        } else {
+            return false;
+        }
+    }
+}
+
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowRuleBatchOperation.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowRuleBatchOperation.java
new file mode 100644
index 0000000..8db1801
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/VirtualFlowRuleBatchOperation.java
@@ -0,0 +1,64 @@
+/*
+ * 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.store.impl.primitives;
+
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+
+import java.util.Objects;
+
+/**
+ * A wrapper class to encapsulate flow rule batch operation.
+ */
+public class VirtualFlowRuleBatchOperation {
+    NetworkId networkId;
+    FlowRuleBatchOperation operation;
+
+    public VirtualFlowRuleBatchOperation(NetworkId networkId,
+                                         FlowRuleBatchOperation operation) {
+        this.networkId = networkId;
+        this.operation = operation;
+    }
+
+    public NetworkId networkId() {
+        return networkId;
+    }
+
+    public FlowRuleBatchOperation operation() {
+        return operation;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(networkId, operation);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this ==  other) {
+            return true;
+        }
+
+        if (other instanceof VirtualFlowRuleBatchOperation) {
+            VirtualFlowRuleBatchOperation that = (VirtualFlowRuleBatchOperation) other;
+            return this.networkId.equals(that.networkId) &&
+                    this.operation.equals(that.operation);
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/package-info.java b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/package-info.java
new file mode 100644
index 0000000..ee0de54
--- /dev/null
+++ b/apps/virtual/app/src/main/java/org/onosproject/incubator/net/virtual/store/impl/primitives/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implementation of distributed virtual network store primitives.
+ */
+package org.onosproject.incubator.net.virtual.store.impl.primitives;
diff --git a/apps/virtual/app/src/main/resources/definitions/TenantId.json b/apps/virtual/app/src/main/resources/definitions/TenantId.json
new file mode 100644
index 0000000..237a9c4
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/TenantId.json
@@ -0,0 +1,14 @@
+{
+  "type": "object",
+  "title": "TenantId",
+  "required": [
+    "id"
+  ],
+  "properties": {
+    "id": {
+      "type": "String",
+      "description": "Tenant identifier",
+      "example": "Tenant123"
+    }
+  }
+}
diff --git a/apps/virtual/app/src/main/resources/definitions/TenantIds.json b/apps/virtual/app/src/main/resources/definitions/TenantIds.json
new file mode 100644
index 0000000..f568b9f
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/TenantIds.json
@@ -0,0 +1,30 @@
+{
+  "type": "object",
+  "title": "tenants",
+  "required": [
+    "tenants"
+  ],
+  "properties": {
+    "tenants": {
+      "type": "array",
+      "xml": {
+        "name": "tenants",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "tenant",
+        "required": [
+          "id"
+        ],
+        "properties": {
+          "id": {
+            "type": "String",
+            "description": "Tenant identifier",
+            "example": "Tenant123"
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/apps/virtual/app/src/main/resources/definitions/VirtualDevice.json b/apps/virtual/app/src/main/resources/definitions/VirtualDevice.json
new file mode 100644
index 0000000..ada054c
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/VirtualDevice.json
@@ -0,0 +1,20 @@
+{
+  "type": "object",
+  "title": "vdev",
+  "required": [
+    "networkId",
+    "deviceId"
+  ],
+  "properties": {
+    "networkId": {
+      "type": "int64",
+      "description": "Network identifier",
+      "example": 3
+    },
+    "deviceId": {
+      "type": "String",
+      "description": "Device identifier",
+      "example": "of:0000000000000042"
+    }
+  }
+}
diff --git a/apps/virtual/app/src/main/resources/definitions/VirtualDevices.json b/apps/virtual/app/src/main/resources/definitions/VirtualDevices.json
new file mode 100644
index 0000000..61e4071
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/VirtualDevices.json
@@ -0,0 +1,36 @@
+{
+  "type": "object",
+  "title": "VirtualDevices",
+  "required": [
+    "devices"
+  ],
+  "properties": {
+    "devices": {
+      "type": "array",
+      "xml": {
+        "name": "devices",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "vdev",
+        "required": [
+          "networkId",
+          "deviceId"
+        ],
+        "properties": {
+          "networkId": {
+            "type": "int64",
+            "description": "Network identifier",
+            "example": 3
+          },
+          "deviceId": {
+            "type": "String",
+            "description": "Device identifier",
+            "example": "of:0000000000000042"
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/apps/virtual/app/src/main/resources/definitions/VirtualHost.json b/apps/virtual/app/src/main/resources/definitions/VirtualHost.json
new file mode 100644
index 0000000..4035694
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/VirtualHost.json
@@ -0,0 +1,63 @@
+{
+  "type": "object",
+  "title": "host",
+  "required": [
+    "networkId",
+    "id",
+    "mac",
+    "vlan",
+    "ipAddresses",
+    "location"
+  ],
+  "properties": {
+    "networkId": {
+      "type": "int64",
+      "description": "Network identifier",
+      "example": 3
+    },
+    "id": {
+      "type": "string",
+      "example": "46:E4:3C:A4:17:C8/-1"
+    },
+    "mac": {
+      "type": "string",
+      "example": "46:E4:3C:A4:17:C8"
+    },
+    "vlan": {
+      "type": "string",
+      "example": "-1"
+    },
+    "ipAddresses": {
+      "type": "array",
+      "xml": {
+        "name": "hosts",
+        "wrapped": true
+      },
+      "items": {
+        "type": "string",
+        "example": "127.0.0.1"
+      }
+    },
+    "locations": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "title": "location",
+        "required": [
+          "elementId",
+          "port"
+        ],
+        "properties": {
+          "elementId": {
+            "type": "string",
+            "example": "of:0000000000000002"
+          },
+          "port": {
+            "type": "string",
+            "example": "3"
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/apps/virtual/app/src/main/resources/definitions/VirtualHostPut.json b/apps/virtual/app/src/main/resources/definitions/VirtualHostPut.json
new file mode 100644
index 0000000..3026478
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/VirtualHostPut.json
@@ -0,0 +1,58 @@
+{
+  "type": "object",
+  "title": "host",
+  "required": [
+    "networkId",
+    "mac",
+    "vlan",
+    "ipAddresses",
+    "location"
+  ],
+  "properties": {
+    "networkId": {
+      "type": "int64",
+      "description": "Network identifier",
+      "example": 3
+    },
+    "mac": {
+      "type": "string",
+      "example": "46:E4:3C:A4:17:C8"
+    },
+    "vlan": {
+      "type": "string",
+      "example": "-1"
+    },
+    "ipAddresses": {
+      "type": "array",
+      "xml": {
+        "name": "hosts",
+        "wrapped": true
+      },
+      "items": {
+        "type": "string",
+        "example": "127.0.0.1"
+      }
+    },
+    "locations": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "title": "location",
+        "required": [
+          "elementId",
+          "port"
+        ],
+        "properties": {
+          "elementId": {
+            "type": "string",
+            "example": "of:0000000000000002"
+          },
+          "port": {
+            "type": "string",
+            "example": "3"
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/apps/virtual/app/src/main/resources/definitions/VirtualHosts.json b/apps/virtual/app/src/main/resources/definitions/VirtualHosts.json
new file mode 100644
index 0000000..979a3f7
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/VirtualHosts.json
@@ -0,0 +1,79 @@
+{
+  "type": "object",
+  "title": "hosts",
+  "required": [
+    "hosts"
+  ],
+  "properties": {
+    "hosts": {
+      "type": "array",
+      "xml": {
+        "name": "hosts",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "host",
+        "required": [
+          "networkId",
+          "id",
+          "mac",
+          "vlan",
+          "ipAddresses",
+          "location"
+        ],
+        "properties": {
+          "networkId": {
+            "type": "int64",
+            "description": "Network identifier",
+            "example": 3
+          },
+          "id": {
+            "type": "string",
+            "example": "46:E4:3C:A4:17:C8/-1"
+          },
+          "mac": {
+            "type": "string",
+            "example": "46:E4:3C:A4:17:C8"
+          },
+          "vlan": {
+            "type": "string",
+            "example": "-1"
+          },
+          "ipAddresses": {
+            "type": "array",
+            "xml": {
+              "name": "hosts",
+              "wrapped": true
+            },
+            "items": {
+              "type": "string",
+              "example": "127.0.0.1"
+            }
+          },
+          "locations": {
+            "type": "array",
+            "items": {
+              "type": "object",
+              "title": "location",
+              "required": [
+                "elementId",
+                "port"
+              ],
+              "properties": {
+                "elementId": {
+                  "type": "string",
+                  "example": "of:0000000000000002"
+                },
+                "port": {
+                  "type": "string",
+                  "example": "3"
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/apps/virtual/app/src/main/resources/definitions/VirtualLink.json b/apps/virtual/app/src/main/resources/definitions/VirtualLink.json
new file mode 100644
index 0000000..8550eb4
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/VirtualLink.json
@@ -0,0 +1,62 @@
+{
+  "type": "object",
+  "title": "vlink",
+  "required": [
+    "networkId",
+    "src",
+    "dst",
+    "type",
+    "state"
+  ],
+  "properties": {
+    "networkId": {
+      "type": "int64",
+      "description": "Network identifier",
+      "example": 3
+    },
+    "src": {
+      "type": "object",
+      "title": "src",
+      "required": [
+        "port",
+        "device"
+      ],
+      "properties": {
+        "port": {
+          "type": "int64",
+          "example": 3
+        },
+        "device": {
+          "type": "string",
+          "example": "of:0000000000000002"
+        }
+      }
+    },
+    "dst": {
+      "type": "object",
+      "title": "dst",
+      "required": [
+        "port",
+        "device"
+      ],
+      "properties": {
+        "port": {
+          "type": "int64",
+          "example": 2
+        },
+        "device": {
+          "type": "string",
+          "example": "of:0000000000000003"
+        }
+      }
+    },
+    "type": {
+      "type": "string",
+      "example": "DIRECT"
+    },
+    "state": {
+      "type": "string",
+      "example": "ACTIVE"
+    }
+  }
+}
diff --git a/apps/virtual/app/src/main/resources/definitions/VirtualLinks.json b/apps/virtual/app/src/main/resources/definitions/VirtualLinks.json
new file mode 100644
index 0000000..8163356
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/VirtualLinks.json
@@ -0,0 +1,78 @@
+{
+  "type": "object",
+  "title": "VirtualLinks",
+  "required": [
+    "links"
+  ],
+  "properties": {
+    "links": {
+      "type": "array",
+      "xml": {
+        "name": "links",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "vlink",
+        "required": [
+          "networkId",
+          "src",
+          "dst",
+          "type",
+          "state"
+        ],
+        "properties": {
+          "networkId": {
+            "type": "int64",
+            "description": "Network identifier",
+            "example": 3
+          },
+          "src": {
+            "type": "object",
+            "title": "src",
+            "required": [
+              "port",
+              "device"
+            ],
+            "properties": {
+              "port": {
+                "type": "int64",
+                "example": 3
+              },
+              "device": {
+                "type": "string",
+                "example": "of:0000000000000002"
+              }
+            }
+          },
+          "dst": {
+            "type": "object",
+            "title": "dst",
+            "required": [
+              "port",
+              "device"
+            ],
+            "properties": {
+              "port": {
+                "type": "int64",
+                "example": 2
+              },
+              "device": {
+                "type": "string",
+                "example": "of:0000000000000003"
+              }
+            }
+          },
+          "type": {
+            "type": "string",
+            "example": "VIRTUAL"
+          },
+          "state": {
+            "type": "string",
+            "example": "ACTIVE"
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/apps/virtual/app/src/main/resources/definitions/VirtualNetworks.json b/apps/virtual/app/src/main/resources/definitions/VirtualNetworks.json
new file mode 100644
index 0000000..6ab1bde
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/VirtualNetworks.json
@@ -0,0 +1,36 @@
+{
+  "type": "object",
+  "title": "VirtualNetworks",
+  "required": [
+    "vnets"
+  ],
+  "properties": {
+    "vnets": {
+      "type": "array",
+      "xml": {
+        "name": "vnets",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "vnet",
+        "required": [
+          "networkId",
+          "tenantId"
+        ],
+        "properties": {
+          "networkId": {
+            "type": "int64",
+            "description": "Network identifier",
+            "example": 3
+          },
+          "tenantId": {
+            "type": "String",
+            "description": "Tenant identifier",
+            "example": "Tenant123"
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/apps/virtual/app/src/main/resources/definitions/VirtualPort.json b/apps/virtual/app/src/main/resources/definitions/VirtualPort.json
new file mode 100644
index 0000000..d1b8e47
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/VirtualPort.json
@@ -0,0 +1,38 @@
+{
+  "type": "object",
+  "title": "vport",
+  "required": [
+    "networkId",
+    "deviceId",
+    "portNum",
+    "physDeviceId",
+    "physPortNum"
+  ],
+  "properties": {
+    "networkId": {
+      "type": "int64",
+      "description": "Network identifier",
+      "example": 3
+    },
+    "deviceId": {
+      "type": "String",
+      "description": "Virtual device identifier",
+      "example": "of:0000000000000042"
+    },
+    "portNum": {
+      "type": "int64",
+      "description": "Virtual device port number",
+      "example": 34
+    },
+    "physDeviceId": {
+      "type": "String",
+      "description": "Physical device identifier",
+      "example": "of:0000000000000003"
+    },
+    "physPortNum": {
+      "type": "int64",
+      "description": "Physical device port number",
+      "example": 2
+    }
+  }
+}
diff --git a/apps/virtual/app/src/main/resources/definitions/VirtualPorts.json b/apps/virtual/app/src/main/resources/definitions/VirtualPorts.json
new file mode 100644
index 0000000..daa5019
--- /dev/null
+++ b/apps/virtual/app/src/main/resources/definitions/VirtualPorts.json
@@ -0,0 +1,54 @@
+{
+  "type": "object",
+  "title": "VirtualPorts",
+  "required": [
+    "ports"
+  ],
+  "properties": {
+    "ports": {
+      "type": "array",
+      "xml": {
+        "name": "ports",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "vport",
+        "required": [
+          "networkId",
+          "deviceId",
+          "portNum",
+          "physDeviceId",
+          "physPortNum"
+        ],
+        "properties": {
+          "networkId": {
+            "type": "int64",
+            "description": "Network identifier",
+            "example": 3
+          },
+          "deviceId": {
+            "type": "String",
+            "description": "Virtual device identifier",
+            "example": "of:0000000000000042"
+          },
+          "portNum": {
+            "type": "int64",
+            "description": "Virtual device port number",
+            "example": 34
+          },
+          "physDeviceId": {
+            "type": "String",
+            "description": "Physical device identifier",
+            "example": "of:0000000000000003"
+          },
+          "physPortNum": {
+            "type": "int64",
+            "description": "Physical device port number",
+            "example": 2
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/AbstractVirtualListenerManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/AbstractVirtualListenerManagerTest.java
new file mode 100644
index 0000000..bc0d32e
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/AbstractVirtualListenerManagerTest.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2018-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;
+
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.MutableClassToInstanceMap;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.event.Event;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.event.EventListener;
+import org.onosproject.event.EventSink;
+import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
+import org.onosproject.incubator.net.virtual.event.VirtualEvent;
+import org.onosproject.incubator.net.virtual.event.VirtualListenerRegistryManager;
+import org.onosproject.net.TenantId;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.*;
+
+/**
+ * Test of the virtual event dispatcher mechanism.
+ */
+public class AbstractVirtualListenerManagerTest {
+
+    private TestEventDispatcher dispatcher = new TestEventDispatcher();
+    private VirtualListenerRegistryManager listenerRegistryManager =
+            VirtualListenerRegistryManager.getInstance();
+
+    private PrickleManager prickleManager;
+    private PrickleListener prickleListener;
+
+    private GooManager gooManager;
+    private GooListener gooListener;
+
+    private BarManager barManager;
+    private BarListener barListener;
+
+    @Before
+    public void setUp() {
+        VirtualNetworkService manager = new TestVirtualNetworkManager();
+
+        dispatcher.addSink(VirtualEvent.class, listenerRegistryManager);
+
+        prickleListener = new PrickleListener();
+        prickleManager = new PrickleManager(manager, NetworkId.networkId(1));
+        prickleManager.addListener(prickleListener);
+
+        gooListener = new GooListener();
+        gooManager = new GooManager(manager, NetworkId.networkId(1));
+        gooManager.addListener(gooListener);
+
+        barListener = new BarListener();
+        barManager = new BarManager(manager, NetworkId.networkId(2));
+        barManager.addListener(barListener);
+    }
+
+    @After
+    public void tearDown() {
+        dispatcher.removeSink(VirtualEvent.class);
+
+        prickleListener.events.clear();
+        gooListener.events.clear();
+        barListener.events.clear();
+
+        prickleListener.latch = null;
+        gooListener.latch = null;
+        barListener.latch = null;
+    }
+
+    @Test
+    public void postPrickle() throws InterruptedException {
+        prickleListener.latch = new CountDownLatch(1);
+        prickleManager.post(new Prickle("prickle"));
+        prickleListener.latch.await(100, TimeUnit.MILLISECONDS);
+
+        validate(prickleListener, "prickle");
+        validate(gooListener);
+        validate(barListener);
+    }
+
+    @Test
+    public void postGoo() throws InterruptedException {
+        gooListener.latch = new CountDownLatch(1);
+        gooManager.post(new Goo("goo"));
+        gooListener.latch.await(100, TimeUnit.MILLISECONDS);
+
+        validate(prickleListener);
+        validate(gooListener, "goo");
+        validate(barListener);
+    }
+
+    @Test
+    public void postBar() throws InterruptedException {
+        barListener.latch = new CountDownLatch(1);
+        barManager.post(new Bar("bar"));
+        barListener.latch.await(100, TimeUnit.MILLISECONDS);
+
+        validate(prickleListener);
+        validate(gooListener);
+        validate(barListener, "bar");
+    }
+
+    @Test
+    public void postEventWithNoListener() throws Exception {
+        dispatcher.post(new Thing("boom"));
+
+        validate(prickleListener);
+        validate(gooListener);
+        validate(barListener);
+    }
+
+    private void validate(TestListener listener, String... strings) {
+        int i = 0;
+        assertEquals("incorrect event count", strings.length, listener.events.size());
+        for (String string : strings) {
+            Event event = (Event) listener.events.get(i++);
+            assertEquals("incorrect event", string, event.subject());
+        }
+    }
+
+    private enum Type { FOO }
+
+    private static class Thing extends AbstractEvent<Type, String> {
+        protected Thing(String subject) {
+            super(Type.FOO, subject);
+        }
+    }
+
+    private static final class Prickle extends Thing {
+        private Prickle(String subject) {
+            super(subject);
+        }
+    }
+
+    private static final class Goo extends Thing {
+        private Goo(String subject) {
+            super(subject);
+        }
+    }
+
+    private static final class Bar extends Thing {
+        private Bar(String subject) {
+            super(subject);
+        }
+    }
+
+    private class TestListener<E extends Event> implements EventListener<E> {
+        List<E> events = new ArrayList<>();
+        CountDownLatch latch;
+
+        @Override
+        public void event(E event) {
+            events.add(event);
+            latch.countDown();
+        }
+    }
+
+    private class PrickleListener extends TestListener<Prickle> {
+    }
+
+    private class GooListener extends TestListener<Goo> {
+    }
+
+    private class BarListener extends TestListener<Bar> {
+    }
+
+    private class PrickleManager extends AbstractVirtualListenerManager<Prickle, PrickleListener> {
+        public PrickleManager(VirtualNetworkService service, NetworkId networkId) {
+            super(service, networkId, Prickle.class);
+        }
+
+        @Override
+        protected void post(Prickle event) {
+            super.post(event);
+        }
+    }
+
+    private class GooManager extends AbstractVirtualListenerManager<Goo, GooListener> {
+        public GooManager(VirtualNetworkService service, NetworkId networkId) {
+            super(service, networkId, Goo.class);
+        }
+
+        @Override
+        protected void post(Goo event) {
+            super.post(event);
+        }
+    }
+
+    private class BarManager extends AbstractVirtualListenerManager<Bar, BarListener> {
+        public BarManager(VirtualNetworkService service, NetworkId networkId) {
+            super(service, networkId, Bar.class);
+        }
+
+        @Override
+        protected void post(Bar event) {
+            super.post(event);
+        }
+    }
+
+
+    private class TestEventDispatcher implements EventDeliveryService {
+        private EventSink sink;
+
+        @Override
+        public <E extends Event> void addSink(Class<E> eventClass, EventSink<E> sink) {
+            this.sink = sink;
+        }
+
+        @Override
+        public <E extends Event> void removeSink(Class<E> eventClass) {
+            this.sink = null;
+        }
+
+        @Override
+        public <E extends Event> EventSink<E> getSink(Class<E> eventClass) {
+            return null;
+        }
+
+        @Override
+        public Set<Class<? extends Event>> getSinks() {
+            return null;
+        }
+
+        @Override
+        public void setDispatchTimeLimit(long millis) {
+
+        }
+
+        @Override
+        public long getDispatchTimeLimit() {
+            return 0;
+        }
+
+        @Override
+        public void post(Event event) {
+            if (event instanceof VirtualEvent) {
+                sink.process(event);
+            }
+        }
+    }
+
+    private class TestVirtualNetworkManager extends VirtualNetworkServiceAdapter {
+        TestServiceDirectory serviceDirectory = new TestServiceDirectory();
+
+        public TestVirtualNetworkManager() {
+            serviceDirectory.add(EventDeliveryService.class, dispatcher);
+        }
+
+        @Override
+        public VirtualNetwork getVirtualNetwork(NetworkId networkId) {
+            return null;
+        }
+
+        @Override
+        public TenantId getTenantId(NetworkId networkId) {
+            return null;
+        }
+
+        @Override
+        public ServiceDirectory getServiceDirectory() {
+            return serviceDirectory;
+        }
+    }
+
+    private  class TestServiceDirectory implements ServiceDirectory {
+
+        private ClassToInstanceMap<Object> services = MutableClassToInstanceMap.create();
+
+        @Override
+        public <T> T get(Class<T> serviceClass) {
+            return services.getInstance(serviceClass);
+        }
+
+        /**
+         * Adds a new service to the directory.
+         *
+         * @param serviceClass service class
+         * @param service service instance
+         * @return self
+         */
+        public TestServiceDirectory add(Class serviceClass, Object service) {
+            services.putInstance(serviceClass, service);
+            return this;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminServiceAdapter.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminServiceAdapter.java
new file mode 100644
index 0000000..4fbed2f
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminServiceAdapter.java
@@ -0,0 +1,126 @@
+/*
+ * 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;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TenantId;
+
+import java.util.Set;
+
+/**
+ * Test adapter for virtual network admin service.
+ */
+public class VirtualNetworkAdminServiceAdapter
+        extends VirtualNetworkServiceAdapter
+        implements VirtualNetworkAdminService {
+
+    @Override
+    public void registerTenantId(TenantId tenantId) {
+
+    }
+
+    @Override
+    public void unregisterTenantId(TenantId tenantId) {
+
+    }
+
+    @Override
+    public Set<TenantId> getTenantIds() {
+        return null;
+    }
+
+    @Override
+    public VirtualNetwork createVirtualNetwork(TenantId tenantId) {
+        return null;
+    }
+
+    @Override
+    public void removeVirtualNetwork(NetworkId networkId) {
+
+    }
+
+    @Override
+    public VirtualDevice createVirtualDevice(NetworkId networkId, DeviceId deviceId) {
+        return null;
+    }
+
+    @Override
+    public void removeVirtualDevice(NetworkId networkId, DeviceId deviceId) {
+
+    }
+
+    @Override
+    public VirtualHost createVirtualHost(NetworkId networkId, HostId hostId,
+                                         MacAddress mac, VlanId vlan,
+                                         HostLocation location, Set<IpAddress> ips) {
+        return null;
+    }
+
+    @Override
+    public void removeVirtualHost(NetworkId networkId, HostId hostId) {
+
+    }
+
+    @Override
+    public VirtualLink createVirtualLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
+        return null;
+    }
+
+    @Override
+    public void removeVirtualLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
+
+    }
+
+    @Override
+    public VirtualPort createVirtualPort(NetworkId networkId, DeviceId deviceId,
+                                         PortNumber portNumber, ConnectPoint realizedBy) {
+        return null;
+    }
+
+    @Override
+    public void bindVirtualPort(NetworkId networkId, DeviceId deviceId,
+                                PortNumber portNumber, ConnectPoint realizedBy) {
+
+    }
+
+    @Override
+    public void updatePortState(NetworkId networkId, DeviceId deviceId, PortNumber portNumber, boolean isEnabled) {
+
+    }
+
+    @Override
+    public void removeVirtualPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
+
+    }
+
+    @Override
+    public VirtualNetwork getVirtualNetwork(NetworkId networkId) {
+        return null;
+    }
+
+    @Override
+    public TenantId getTenantId(NetworkId networkId) {
+        return null;
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkServiceAdapter.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkServiceAdapter.java
new file mode 100644
index 0000000..9420d60
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkServiceAdapter.java
@@ -0,0 +1,84 @@
+/*
+ * 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;
+
+import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.TenantId;
+
+import java.util.Set;
+
+/**
+ * Test adapter for virtual network service.
+ */
+public abstract class VirtualNetworkServiceAdapter implements VirtualNetworkService {
+    @Override
+    public void addListener(VirtualNetworkListener listener) {
+
+    }
+
+    @Override
+    public void removeListener(VirtualNetworkListener listener) {
+
+    }
+
+    @Override
+    public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
+        return null;
+    }
+
+    @Override
+    public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
+        return null;
+    }
+
+    @Override
+    public Set<VirtualHost> getVirtualHosts(NetworkId networkId) {
+        return null;
+    }
+
+    @Override
+    public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
+        return null;
+    }
+
+    @Override
+    public Set<VirtualPort> getVirtualPorts(NetworkId networkId, DeviceId deviceId) {
+        return null;
+    }
+
+    @Override
+    public Set<DeviceId> getPhysicalDevices(NetworkId networkId, DeviceId deviceId) {
+        return null;
+    }
+
+    @Override
+    public <T> T get(NetworkId networkId, Class<T> serviceClass) {
+        return null;
+    }
+
+    @Override
+    public ServiceDirectory getServiceDirectory() {
+        return null;
+    }
+
+    @Override
+    public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) {
+        return null;
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/TestCoreService.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/TestCoreService.java
new file mode 100644
index 0000000..80b74df
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/TestCoreService.java
@@ -0,0 +1,39 @@
+/*
+ * 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 org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Core service test class.
+ */
+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/VirtualNetworkDeviceManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManagerTest.java
new file mode 100644
index 0000000..63681e8
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManagerTest.java
@@ -0,0 +1,493 @@
+/*
+ * 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.Test;
+import org.onlab.junit.TestTools;
+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.event.EventDeliveryService;
+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.VirtualPort;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.Port;
+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.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.*;
+
+/**
+ * Junit tests for VirtualNetworkDeviceService.
+ */
+public class VirtualNetworkDeviceManagerTest extends VirtualNetworkTestUtil {
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService;
+    private TestServiceDirectory testDirectory;
+    private TestListener testListener = new TestListener();
+    private TestEventDispatcher dispatcher = new TestEventDispatcher();
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        coreService = new VirtualNetworkDeviceManagerTest.TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, dispatcher);
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+    }
+
+    /**
+     * Tests the getDevices(), getAvailableDevices(), getDeviceCount(), getDevice(), and isAvailable() methods.
+     */
+    @Test
+    public void testGetDevices() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice device1 = manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice device2 = manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getDevices() method
+        Iterator<Device> it = deviceService.getDevices().iterator();
+        assertEquals("The device set size did not match.", 2, Iterators.size(it));
+
+        // test the getAvailableDevices() method
+        Iterator<Device> it2 = deviceService.getAvailableDevices().iterator();
+        assertEquals("The device set size did not match.", 2, Iterators.size(it2));
+
+        // test the getDeviceCount() method
+        assertEquals("The device set size did not match.", 2, deviceService.getDeviceCount());
+
+        // test the getDevice() method
+        assertEquals("The expect device did not match.", device1,
+                     deviceService.getDevice(DID1));
+        assertNotEquals("The expect device should not have matched.", device1,
+                        deviceService.getDevice(DID2));
+
+        // test the isAvailable() method
+        assertTrue("The expect device availability did not match.",
+                   deviceService.isAvailable(DID1));
+        assertFalse("The expect device availability did not match.",
+                    deviceService.isAvailable(DID3));
+    }
+
+    /**
+     * Tests querying for a device using a null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDeviceByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getDevice() method with null device id value.
+        deviceService.getDevice(null);
+    }
+
+    /**
+     * Tests querying for a device using a null device type.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDeviceByNullType() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getDevices() method with null type value.
+        deviceService.getDevices(null);
+    }
+
+    /**
+     * Tests the isAvailable method using a null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsAvailableByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the isAvailable() method with null device id value.
+        deviceService.isAvailable(null);
+    }
+
+    /**
+     * Tests querying for a device and available devices by device type.
+     */
+    @Test
+    public void testGetDeviceType() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getDevices(Type) method.
+        Iterator<Device> it = deviceService.getDevices(Device.Type.VIRTUAL).iterator();
+        assertEquals("The device set size did not match.", 2, Iterators.size(it));
+        Iterator<Device> it2 = deviceService.getDevices(Device.Type.SWITCH).iterator();
+        assertEquals("The device set size did not match.", 0, Iterators.size(it2));
+
+        // test the getAvailableDevices(Type) method.
+        Iterator<Device> it3 = deviceService.getAvailableDevices(Device.Type.VIRTUAL).iterator();
+        assertEquals("The device set size did not match.", 2, Iterators.size(it3));
+    }
+
+    /**
+     * Tests querying the role of a device by null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetRoleByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getRole() method using a null device identifier
+        deviceService.getRole(null);
+    }
+
+    /**
+     * Tests querying the role of a device by device identifier.
+     */
+    @Test
+    public void testGetRole() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getRole() method
+        assertEquals("The expect device role did not match.", MastershipRole.MASTER,
+                     deviceService.getRole(DID1));
+    }
+
+    /**
+     * Tests querying the ports of a device by null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPortsByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getPorts() method using a null device identifier
+        deviceService.getPorts(null);
+    }
+
+    /**
+     * Tests querying the ports of a device by device identifier.
+     */
+    @Test
+    public void testGetPorts() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice = manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        ConnectPoint cp = new ConnectPoint(virtualDevice.id(), PortNumber.portNumber(1));
+
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice.id(), PortNumber.portNumber(1), cp);
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice.id(), PortNumber.portNumber(2), cp);
+
+        // test the getPorts() method
+        assertEquals("The port set size did not match.", 2,
+                     deviceService.getPorts(DID1).size());
+        assertEquals("The port set size did not match.", 0,
+                     deviceService.getPorts(DID2).size());
+    }
+
+    /**
+     * Tests querying the port of a device by device identifier and port number.
+     */
+    @Test
+    public void testGetPort() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice = manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        ConnectPoint cp = new ConnectPoint(virtualDevice.id(), PortNumber.portNumber(1));
+
+        VirtualPort virtualPort1 = manager.createVirtualPort(virtualNetwork.id(), virtualDevice.id(),
+                                                             PortNumber.portNumber(1), cp);
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice.id(), PortNumber.portNumber(2), cp);
+
+        // test the getPort() method
+        assertEquals("The port did not match as expected.", virtualPort1,
+                     deviceService.getPort(DID1, PortNumber.portNumber(1)));
+        assertNotEquals("The port did not match as expected.", virtualPort1,
+                        deviceService.getPort(DID1, PortNumber.portNumber(3)));
+    }
+
+    /**
+     * Tests querying the port statistics of a device by null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPortsStatisticsByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getPortStatistics() method using a null device identifier
+        deviceService.getPortStatistics(null);
+    }
+
+    /**
+     * Tests querying the port statistics of a device by device identifier.
+     */
+    @Test
+    public void testGetPortStatistics() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice = manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getPortStatistics() method
+        assertEquals("The port statistics set size did not match.", 0,
+                     deviceService.getPortStatistics(DID1).size());
+    }
+
+    /**
+     * Tests querying the port delta statistics of a device by null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPortsDeltaStatisticsByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getPortDeltaStatistics() method using a null device identifier
+        deviceService.getPortDeltaStatistics(null);
+    }
+
+    /**
+     * Tests querying the port delta statistics of a device by device identifier.
+     */
+    @Test
+    public void testGetPortDeltaStatistics() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice = manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getPortDeltaStatistics() method
+        assertEquals("The port delta statistics set size did not match.", 0,
+                     deviceService.getPortDeltaStatistics(DID1).size());
+    }
+
+    /**
+     * Tests DeviceEvents received during virtual device/port addition and removal.
+     */
+    @Test
+    public void testDeviceEventsForAddRemovalDeviceAndPorts() throws TestUtils.TestUtilsException {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        // add virtual device before virtual device manager is created
+        VirtualDevice device1 = manager.createVirtualDevice(virtualNetwork.id(), VDID1);
+        validateEvents(); // no DeviceEvent expected
+
+        testDirectory.add(EventDeliveryService.class, dispatcher);
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // virtual device manager is created; register DeviceEvent listener
+        deviceService.addListener(testListener);
+
+        // list to keep track of expected event types
+        List<DeviceEvent.Type> expectedEventTypes = new ArrayList<>();
+
+        // add virtual device
+        VirtualDevice device2 = manager.createVirtualDevice(virtualNetwork.id(), VDID2);
+        expectedEventTypes.add(DeviceEvent.Type.DEVICE_ADDED);
+
+        ConnectPoint cp = new ConnectPoint(PHYDID1, PortNumber.portNumber(1));
+
+        // add 2 virtual ports
+        manager.createVirtualPort(virtualNetwork.id(),
+                                  device2.id(), PortNumber.portNumber(1), cp);
+        expectedEventTypes.add(DeviceEvent.Type.PORT_ADDED);
+        manager.createVirtualPort(virtualNetwork.id(),
+                                  device2.id(), PortNumber.portNumber(2), cp);
+        expectedEventTypes.add(DeviceEvent.Type.PORT_ADDED);
+
+        // verify virtual ports were added
+        Set<VirtualPort> virtualPorts = manager.getVirtualPorts(virtualNetwork.id(), device2.id());
+        assertNotNull("The virtual port set should not be null", virtualPorts);
+        assertEquals("The virtual port set size did not match.", 2, virtualPorts.size());
+        virtualPorts.forEach(vp -> assertFalse("Initial virtual port state should be disabled", vp.isEnabled()));
+
+        // verify change state of virtual port (disabled -> enabled)
+        manager.updatePortState(virtualNetwork.id(), device2.id(), PortNumber.portNumber(1), true);
+        Port changedPort = deviceService.getPort(device2.id(), PortNumber.portNumber(1));
+        assertNotNull("The changed virtual port should not be null", changedPort);
+        assertEquals("Virtual port state should be enabled", true, changedPort.isEnabled());
+        expectedEventTypes.add(DeviceEvent.Type.PORT_UPDATED);
+
+        // verify change state of virtual port (disabled -> disabled)
+        manager.updatePortState(virtualNetwork.id(), device2.id(), PortNumber.portNumber(2), false);
+        changedPort = deviceService.getPort(device2.id(), PortNumber.portNumber(2));
+        assertNotNull("The changed virtual port should not be null", changedPort);
+        assertEquals("Virtual port state should be disabled", false, changedPort.isEnabled());
+        // no VIRTUAL_PORT_UPDATED event is expected - the requested state (disabled) is same as previous state.
+
+        // remove 2 virtual ports
+        for (VirtualPort virtualPort : virtualPorts) {
+            manager.removeVirtualPort(virtualNetwork.id(),
+                                      (DeviceId) virtualPort.element().id(), virtualPort.number());
+            expectedEventTypes.add(DeviceEvent.Type.PORT_REMOVED);
+            // attempt to remove the same virtual port again - no DeviceEvent.Type.PORT_REMOVED expected.
+            manager.removeVirtualPort(virtualNetwork.id(),
+                                      (DeviceId) virtualPort.element().id(), virtualPort.number());
+        }
+
+        // verify virtual ports were removed
+        virtualPorts = manager.getVirtualPorts(virtualNetwork.id(), device2.id());
+        assertTrue("The virtual port set should be empty.", virtualPorts.isEmpty());
+
+        // Add/remove one virtual port again.
+        VirtualPort virtualPort =
+                manager.createVirtualPort(virtualNetwork.id(), device2.id(),
+                                                            PortNumber.portNumber(1), cp);
+        expectedEventTypes.add(DeviceEvent.Type.PORT_ADDED);
+
+        ConnectPoint newCp = new ConnectPoint(PHYDID3, PortNumber.portNumber(2));
+        manager.bindVirtualPort(virtualNetwork.id(), device2.id(),
+                                PortNumber.portNumber(1), newCp);
+        expectedEventTypes.add(DeviceEvent.Type.PORT_UPDATED);
+
+        manager.removeVirtualPort(virtualNetwork.id(),
+                                  (DeviceId) virtualPort.element().id(), virtualPort.number());
+        expectedEventTypes.add(DeviceEvent.Type.PORT_REMOVED);
+
+        // verify no virtual ports remain
+        virtualPorts = manager.getVirtualPorts(virtualNetwork.id(), device2.id());
+        assertTrue("The virtual port set should be empty.", virtualPorts.isEmpty());
+
+        // remove virtual device
+        manager.removeVirtualDevice(virtualNetwork.id(), device2.id());
+        expectedEventTypes.add(DeviceEvent.Type.DEVICE_REMOVED);
+
+        // Validate that the events were all received in the correct order.
+        validateEvents((Enum[]) expectedEventTypes.toArray(
+                new DeviceEvent.Type[expectedEventTypes.size()]));
+
+        // cleanup
+        deviceService.removeListener(testListener);
+    }
+
+    /**
+     * 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();
+                }
+            };
+        }
+    }
+
+    /**
+     * Method to validate that the actual versus expected virtual network events were
+     * received correctly.
+     *
+     * @param types expected virtual network events.
+     */
+    private void validateEvents(Enum... types) {
+        TestTools.assertAfter(100, () -> {
+            int i = 0;
+            assertEquals("wrong events received", types.length, testListener.events.size());
+            for (Event event : testListener.events) {
+                assertEquals("incorrect event type", types[i], event.type());
+                i++;
+            }
+            testListener.events.clear();
+        });
+    }
+
+    /**
+     * Test listener class to receive device events.
+     */
+    private static class TestListener implements DeviceListener {
+
+        private List<DeviceEvent> events = Lists.newArrayList();
+
+        @Override
+        public void event(DeviceEvent event) {
+            events.add(event);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerTest.java
new file mode 100644
index 0000000..1def419
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerTest.java
@@ -0,0 +1,248 @@
+/*
+ * 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;
+
+import org.junit.After;
+import org.junit.Before;
+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.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowRuleStore;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.TestStorageService;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Junit tests for VirtualNetworkFlowObjectiveManager.
+ */
+public class VirtualNetworkFlowObjectiveManagerTest
+        extends VirtualNetworkTestUtil {
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private ServiceDirectory testDirectory;
+    protected SimpleVirtualFlowObjectiveStore flowObjectiveStore;
+
+    private VirtualProviderManager providerRegistryService;
+    private EventDeliveryService eventDeliveryService;
+
+    private ApplicationId appId;
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private FlowObjectiveService service1;
+    private FlowObjectiveService service2;
+
+    //FIXME: referring flowrule service, store, and provider shouldn't be here
+    private VirtualFlowRuleProvider flowRuleProvider = new TestProvider();
+    private SimpleVirtualFlowRuleStore flowRuleStore;
+    protected StorageService storageService = new TestStorageService();
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", storageService);
+        virtualNetworkManagerStore.activate();
+
+        flowObjectiveStore = new SimpleVirtualFlowObjectiveStore();
+        TestUtils.setField(flowObjectiveStore, "storageService", storageService);
+        flowObjectiveStore.activate();
+        flowRuleStore = new SimpleVirtualFlowRuleStore();
+        flowRuleStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        TestUtils.setField(manager, "coreService", coreService);
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(flowRuleProvider);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+
+        appId = new TestApplicationId("FlowRuleManagerTest");
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(VirtualNetworkFlowRuleStore.class, flowRuleStore)
+                .add(VirtualNetworkFlowObjectiveStore.class, flowObjectiveStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        vnet1 = setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = setupVirtualNetworkTopology(manager, TID2);
+
+        service1 = new VirtualNetworkFlowObjectiveManager(manager, vnet1.id());
+        service2 = new VirtualNetworkFlowObjectiveManager(manager, vnet2.id());
+    }
+
+    @After
+    public void tearDownTest() {
+        manager.deactivate();
+        virtualNetworkManagerStore.deactivate();
+    }
+
+    /**
+     * Tests adding a forwarding objective.
+     */
+    @Test
+    public void forwardingObjective() {
+        TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        ForwardingObjective forward =
+                DefaultForwardingObjective.builder()
+                        .fromApp(NetTestTools.APP_ID)
+                        .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                        .withSelector(selector)
+                        .withTreatment(treatment)
+                        .makePermanent()
+                        .add(new ObjectiveContext() {
+                            @Override
+                            public void onSuccess(Objective objective) {
+                                assertEquals("1 flowrule entry expected",
+                                             1, flowRuleStore.getFlowRuleCount(vnet1.id()));
+                                assertEquals("0 flowrule entry expected",
+                                             0, flowRuleStore.getFlowRuleCount(vnet2.id()));
+                            }
+                        });
+
+        service1.forward(VDID1, forward);
+    }
+
+    /**
+     * Tests adding a next objective.
+     */
+    @Test
+    public void nextObjective() {
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        NextObjective nextObjective = DefaultNextObjective.builder()
+                .withId(service1.allocateNextId())
+                .fromApp(NetTestTools.APP_ID)
+                .addTreatment(treatment)
+                .withType(NextObjective.Type.BROADCAST)
+                .makePermanent()
+                .add(new ObjectiveContext() {
+                    @Override
+                    public void onSuccess(Objective objective) {
+                        assertEquals("1 next map entry expected",
+                                     1, service1.getNextMappings().size());
+                        assertEquals("0 next map entry expected",
+                                     0, service2.getNextMappings().size());
+                    }
+                });
+
+        service1.next(VDID1, nextObjective);
+    }
+
+    /**
+     * Tests adding a filtering objective.
+     */
+    @Test
+    public void filteringObjective() {
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        FilteringObjective filter =
+                DefaultFilteringObjective.builder()
+                        .fromApp(NetTestTools.APP_ID)
+                        .withMeta(treatment)
+                        .makePermanent()
+                        .deny()
+                        .addCondition(Criteria.matchEthType(12))
+                        .add(new ObjectiveContext() {
+                            @Override
+                            public void onSuccess(Objective objective) {
+                                assertEquals("1 flowrule entry expected",
+                                             1,
+                                             flowRuleStore.getFlowRuleCount(vnet1.id()));
+                                assertEquals("0 flowrule entry expected",
+                                             0,
+                                             flowRuleStore.getFlowRuleCount(vnet2.id()));
+
+                            }
+                        });
+
+        service1.filter(VDID1, filter);
+    }
+
+    //TODO: More test cases for filter, forward, and next
+
+    private class TestProvider extends AbstractVirtualProvider
+            implements VirtualFlowRuleProvider {
+
+        protected TestProvider() {
+            super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
+        }
+
+        @Override
+        public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
+
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerWithDistStoreTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerWithDistStoreTest.java
new file mode 100644
index 0000000..78ed454
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerWithDistStoreTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+import org.junit.After;
+import org.junit.Before;
+import org.onlab.junit.TestUtils;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualFlowObjectiveStore;
+
+/**
+ * Junit tests for VirtualNetworkFlowObjectiveManager using
+ * DistributedVirtualFlowObjectiveStore.  This test class extends
+ * VirtualNetworkFlowObjectiveManagerTest - all the tests defined in
+ * VirtualNetworkFlowObjectiveManagerTest will run using
+ * DistributedVirtualFlowObjectiveStore.
+ */
+public class VirtualNetworkFlowObjectiveManagerWithDistStoreTest
+        extends VirtualNetworkFlowObjectiveManagerTest {
+
+    private static final String STORE_FIELDNAME_STORAGESERVICE = "storageService";
+
+    private DistributedVirtualFlowObjectiveStore distStore;
+
+    @Before
+    public void setUp() throws Exception {
+        setupDistFlowObjectiveStore();
+        super.setUp();
+    }
+
+    private void setupDistFlowObjectiveStore() throws TestUtils.TestUtilsException {
+        distStore = new DistributedVirtualFlowObjectiveStore();
+        TestUtils.setField(distStore, STORE_FIELDNAME_STORAGESERVICE, storageService);
+
+        distStore.activate();
+        flowObjectiveStore = distStore; // super.setUp() will cause Distributed store to be used.
+    }
+
+    @After
+    public void tearDown() {
+        distStore.deactivate();
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java
new file mode 100644
index 0000000..037b67f
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java
@@ -0,0 +1,533 @@
+/*
+ * 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.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.junit.After;
+import org.junit.Before;
+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.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowRuleStore;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleListener;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.StoredFlowEntry;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+import static org.onosproject.net.flow.FlowRuleEvent.Type.*;
+
+public class VirtualNetworkFlowRuleManagerTest extends VirtualNetworkTestUtil {
+    private static final int TIMEOUT = 10;
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private ServiceDirectory testDirectory;
+    private VirtualNetworkFlowRuleStore flowRuleStore;
+    private VirtualProviderManager providerRegistryService;
+
+    private EventDeliveryService eventDeliveryService;
+
+    private VirtualNetworkFlowRuleManager vnetFlowRuleService1;
+    private VirtualNetworkFlowRuleManager vnetFlowRuleService2;
+
+    private VirtualFlowRuleProvider provider = new TestProvider();
+    private VirtualFlowRuleProviderService providerService1;
+    private VirtualFlowRuleProviderService providerService2;
+
+    protected TestFlowRuleListener listener1 = new TestFlowRuleListener();
+    protected TestFlowRuleListener listener2 = new TestFlowRuleListener();
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private ApplicationId appId;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        flowRuleStore = new SimpleVirtualFlowRuleStore();
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(provider);
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        TestUtils.setField(manager, "coreService", coreService);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+
+        appId = new TestApplicationId("FlowRuleManagerTest");
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(VirtualNetworkFlowRuleStore.class, flowRuleStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        vnet1 = setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = setupVirtualNetworkTopology(manager, TID2);
+
+        vnetFlowRuleService1 = new VirtualNetworkFlowRuleManager(manager, vnet1.id());
+        vnetFlowRuleService2 = new VirtualNetworkFlowRuleManager(manager, vnet2.id());
+        vnetFlowRuleService1.addListener(listener1);
+        vnetFlowRuleService2.addListener(listener2);
+
+        vnetFlowRuleService1.operationsService = MoreExecutors.newDirectExecutorService();
+        vnetFlowRuleService2.operationsService = MoreExecutors.newDirectExecutorService();
+        vnetFlowRuleService1.deviceInstallers = MoreExecutors.newDirectExecutorService();
+        vnetFlowRuleService2.deviceInstallers = MoreExecutors.newDirectExecutorService();
+
+        providerService1 = (VirtualFlowRuleProviderService)
+                providerRegistryService.getProviderService(vnet1.id(), VirtualFlowRuleProvider.class);
+        providerService2 = (VirtualFlowRuleProviderService)
+                providerRegistryService.getProviderService(vnet2.id(), VirtualFlowRuleProvider.class);
+    }
+
+    @After
+    public void tearDown() {
+        manager.deactivate();
+        virtualNetworkManagerStore.deactivate();
+    }
+
+    private FlowRule flowRule(int tsval, int trval) {
+        return flowRule(VDID1, tsval, trval);
+    }
+
+    private FlowRule flowRule(DeviceId did, int tsval, int trval) {
+        TestSelector ts = new TestSelector(tsval);
+        TestTreatment tr = new TestTreatment(trval);
+        return DefaultFlowRule.builder()
+                .forDevice(did)
+                .withSelector(ts)
+                .withTreatment(tr)
+                .withPriority(10)
+                .fromApp(appId)
+                .makeTemporary(TIMEOUT)
+                .build();
+    }
+
+    private FlowRule addFlowRule(int hval) {
+        FlowRule rule = flowRule(hval, hval);
+        vnetFlowRuleService1.applyFlowRules(rule);
+
+        assertNotNull("rule should be found", vnetFlowRuleService1.getFlowEntries(VDID1));
+        return rule;
+    }
+
+    private int flowCount(FlowRuleService service) {
+        List<FlowEntry> entries = Lists.newArrayList();
+        service.getFlowEntries(VDID1).forEach(entries::add);
+        return entries.size();
+    }
+
+    @Test
+    public void getFlowEntries() {
+        assertTrue("store should be empty",
+                   Sets.newHashSet(vnetFlowRuleService1.getFlowEntries(VDID1)).isEmpty());
+        assertTrue("store should be empty",
+                   Sets.newHashSet(vnetFlowRuleService2.getFlowEntries(VDID1)).isEmpty());
+
+        FlowRule f1 = addFlowRule(1);
+        FlowRule f2 = addFlowRule(2);
+
+        FlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+
+        assertEquals("2 rules should exist", 2, flowCount(vnetFlowRuleService1));
+        assertEquals("0 rules should exist", 0, flowCount(vnetFlowRuleService2));
+
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2));
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
+                       RULE_ADDED, RULE_ADDED);
+
+        addFlowRule(1);
+        assertEquals("should still be 2 rules", 2, flowCount(vnetFlowRuleService1));
+        System.err.println("events :" + listener1.events);
+        assertEquals("0 rules should exist", 0, flowCount(vnetFlowRuleService2));
+
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1));
+        validateEvents(listener1, RULE_UPDATED, RULE_UPDATED);
+    }
+
+    @Test
+    public void applyFlowRules() {
+        FlowRule r1 = flowRule(1, 1);
+        FlowRule r2 = flowRule(2, 2);
+        FlowRule r3 = flowRule(3, 3);
+
+        assertTrue("store should be empty",
+                   Sets.newHashSet(vnetFlowRuleService1.getFlowEntries(DID1)).isEmpty());
+        vnetFlowRuleService1.applyFlowRules(r1, r2, r3);
+        assertEquals("3 rules should exist", 3, flowCount(vnetFlowRuleService1));
+        assertTrue("Entries should be pending add.",
+                   validateState(ImmutableMap.of(
+                           r1, FlowEntry.FlowEntryState.PENDING_ADD,
+                           r2, FlowEntry.FlowEntryState.PENDING_ADD,
+                           r3, FlowEntry.FlowEntryState.PENDING_ADD)));
+    }
+
+    @Test
+    public void purgeFlowRules() {
+        FlowRule f1 = addFlowRule(1);
+        FlowRule f2 = addFlowRule(2);
+        FlowRule f3 = addFlowRule(3);
+        assertEquals("3 rules should exist", 3, flowCount(vnetFlowRuleService1));
+        FlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+        FlowEntry fe3 = new DefaultFlowEntry(f3);
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2, fe3));
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
+                       RULE_ADDED, RULE_ADDED, RULE_ADDED);
+        vnetFlowRuleService1.purgeFlowRules(VDID1);
+        assertEquals("0 rule should exist", 0, flowCount(vnetFlowRuleService1));
+    }
+
+    @Test
+    public void removeFlowRules() {
+        FlowRule f1 = addFlowRule(1);
+        FlowRule f2 = addFlowRule(2);
+        FlowRule f3 = addFlowRule(3);
+        assertEquals("3 rules should exist", 3, flowCount(vnetFlowRuleService1));
+
+        FlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+        FlowEntry fe3 = new DefaultFlowEntry(f3);
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2, fe3));
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
+                       RULE_ADDED, RULE_ADDED, RULE_ADDED);
+
+        vnetFlowRuleService1.removeFlowRules(f1, f2);
+        //removing from north, so no events generated
+        validateEvents(listener1, RULE_REMOVE_REQUESTED, RULE_REMOVE_REQUESTED);
+        assertEquals("3 rule should exist", 3, flowCount(vnetFlowRuleService1));
+        assertTrue("Entries should be pending remove.",
+                   validateState(ImmutableMap.of(
+                           f1, FlowEntry.FlowEntryState.PENDING_REMOVE,
+                           f2, FlowEntry.FlowEntryState.PENDING_REMOVE,
+                           f3, FlowEntry.FlowEntryState.ADDED)));
+
+        vnetFlowRuleService1.removeFlowRules(f1);
+        assertEquals("3 rule should still exist", 3, flowCount(vnetFlowRuleService1));
+    }
+
+    @Test
+    public void flowRemoved() {
+        FlowRule f1 = addFlowRule(1);
+        FlowRule f2 = addFlowRule(2);
+        StoredFlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2));
+        vnetFlowRuleService1.removeFlowRules(f1);
+
+        //FIXME modification of "stored" flow entry outside of store
+        fe1.setState(FlowEntry.FlowEntryState.REMOVED);
+
+        providerService1.flowRemoved(fe1);
+
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED,
+                       RULE_ADDED, RULE_REMOVE_REQUESTED, RULE_REMOVED);
+
+        providerService1.flowRemoved(fe1);
+        validateEvents(listener1);
+
+        FlowRule f3 = flowRule(3, 3);
+        FlowEntry fe3 = new DefaultFlowEntry(f3);
+        vnetFlowRuleService1.applyFlowRules(f3);
+
+        providerService1.pushFlowMetrics(VDID1, Collections.singletonList(fe3));
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADDED, RULE_UPDATED);
+
+        providerService1.flowRemoved(fe3);
+        validateEvents(listener1);
+    }
+
+    @Test
+    public void extraneousFlow() {
+        FlowRule f1 = flowRule(1, 1);
+        FlowRule f2 = flowRule(2, 2);
+        FlowRule f3 = flowRule(3, 3);
+        vnetFlowRuleService1.applyFlowRules(f1, f2);
+
+        FlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+        FlowEntry fe3 = new DefaultFlowEntry(f3);
+
+
+        providerService1.pushFlowMetrics(VDID1, Lists.newArrayList(fe1, fe2, fe3));
+
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
+                       RULE_ADDED, RULE_ADDED);
+    }
+
+    /*
+     * Tests whether a rule that was marked for removal but no flowRemoved was received
+     * is indeed removed at the next stats update.
+     */
+    @Test
+    public void flowMissingRemove() {
+        FlowRule f1 = flowRule(1, 1);
+        FlowRule f2 = flowRule(2, 2);
+        FlowRule f3 = flowRule(3, 3);
+
+        FlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+        vnetFlowRuleService1.applyFlowRules(f1, f2, f3);
+
+        vnetFlowRuleService1.removeFlowRules(f3);
+
+        providerService1.pushFlowMetrics(VDID1, Lists.newArrayList(fe1, fe2));
+
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
+                       RULE_REMOVE_REQUESTED, RULE_ADDED, RULE_ADDED, RULE_REMOVED);
+    }
+
+    @Test
+    public void removeByAppId() {
+        FlowRule f1 = flowRule(1, 1);
+        FlowRule f2 = flowRule(2, 2);
+        vnetFlowRuleService1.applyFlowRules(f1, f2);
+
+        vnetFlowRuleService1.removeFlowRulesById(appId);
+
+        //only check that we are in pending remove. Events and actual remove state will
+        // be set by flowRemoved call.
+        validateState(ImmutableMap.of(
+                f1, FlowEntry.FlowEntryState.PENDING_REMOVE,
+                f2, FlowEntry.FlowEntryState.PENDING_REMOVE));
+    }
+
+    //TODO:Tests for fallback
+
+    private boolean validateState(Map<FlowRule, FlowEntry.FlowEntryState> expected) {
+        Map<FlowRule, FlowEntry.FlowEntryState> expectedToCheck = new HashMap<>(expected);
+        Iterable<FlowEntry> rules = vnetFlowRuleService1.getFlowEntries(VDID1);
+        for (FlowEntry f : rules) {
+            assertTrue("Unexpected FlowRule " + f, expectedToCheck.containsKey(f));
+            assertEquals("FlowEntry" + f, expectedToCheck.get(f), f.state());
+            expectedToCheck.remove(f);
+        }
+        assertEquals(Collections.emptySet(), expectedToCheck.entrySet());
+        return true;
+    }
+
+    private class TestSelector implements TrafficSelector {
+
+        //for controlling hashcode uniqueness;
+        private final int testval;
+
+        public TestSelector(int val) {
+            testval = val;
+        }
+
+        @Override
+        public Set<Criterion> criteria() {
+            return Collections.emptySet();
+        }
+
+        @Override
+        public Criterion getCriterion(
+                org.onosproject.net.flow.criteria.Criterion.Type type) {
+            return null;
+        }
+
+        @Override
+        public int hashCode() {
+            return testval;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof TestSelector) {
+                return this.testval == ((TestSelector) o).testval;
+            }
+            return false;
+        }
+    }
+
+    private class TestTreatment implements TrafficTreatment {
+
+        //for controlling hashcode uniqueness;
+        private final int testval;
+
+        public TestTreatment(int val) {
+            testval = val;
+        }
+
+        @Override
+        public List<Instruction> deferred() {
+            return null;
+        }
+
+        @Override
+        public List<Instruction> immediate() {
+            return null;
+        }
+
+        @Override
+        public List<Instruction> allInstructions() {
+            return null;
+        }
+
+        @Override
+        public Instructions.TableTypeTransition tableTransition() {
+            return null;
+        }
+
+        @Override
+        public boolean clearedDeferred() {
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return testval;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof TestTreatment) {
+                return this.testval == ((TestTreatment) o).testval;
+            }
+            return false;
+        }
+
+        @Override
+        public Instructions.MetadataInstruction writeMetadata() {
+            return null;
+        }
+
+        @Override
+        public Instructions.StatTriggerInstruction statTrigger() {
+            return null;
+        }
+
+        @Override
+        public Instructions.MeterInstruction metered() {
+            return null;
+        }
+
+        @Override
+        public Set<Instructions.MeterInstruction> meters() {
+            return Sets.newHashSet();
+        }
+    }
+
+    private void validateEvents(TestFlowRuleListener listener, FlowRuleEvent.Type... events) {
+        if (events == null) {
+            assertTrue("events generated", listener.events.isEmpty());
+        }
+
+        int i = 0;
+        System.err.println("events :" + listener.events);
+        for (FlowRuleEvent e : listener.events) {
+            assertEquals("unexpected event", events[i], e.type());
+            i++;
+        }
+
+        assertEquals("mispredicted number of events",
+                     events.length, listener.events.size());
+
+        listener.events.clear();
+    }
+
+    private class TestFlowRuleListener implements FlowRuleListener {
+
+        public final List<FlowRuleEvent> events = new ArrayList<>();
+
+        @Override
+        public void event(FlowRuleEvent event) {
+            events.add(event);
+        }
+    }
+
+    private class TestProvider extends AbstractVirtualProvider
+            implements VirtualFlowRuleProvider {
+
+        protected TestProvider() {
+            super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
+        }
+
+        @Override
+        public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
+
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkGroupManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkGroupManagerTest.java
new file mode 100644
index 0000000..7aa0d9c
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkGroupManagerTest.java
@@ -0,0 +1,702 @@
+/*
+ * 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;
+
+import com.google.common.collect.Iterables;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+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.GroupId;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkGroupStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualGroupProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualGroupProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualGroupStore;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroup;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupEvent;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupListener;
+import org.onosproject.net.group.GroupOperation;
+import org.onosproject.net.group.GroupOperations;
+import org.onosproject.net.group.StoredGroupEntry;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.*;
+import static org.onosproject.incubator.net.virtual.impl.VirtualNetworkTestUtil.*;
+import static org.onosproject.net.NetTestTools.injectEventDispatcher;
+
+/**
+ * Test codifying the virtual group service & group provider service contracts.
+ */
+public class VirtualNetworkGroupManagerTest {
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private ServiceDirectory testDirectory;
+    private VirtualProviderManager providerRegistryService;
+
+    private EventDeliveryService eventDeliveryService;
+
+    private VirtualNetworkGroupManager groupManager1;
+    private VirtualNetworkGroupManager groupManager2;
+
+    private VirtualNetworkGroupStore groupStore;
+
+    private TestGroupProvider provider = new TestGroupProvider();
+    private VirtualGroupProviderService providerService1;
+    private VirtualGroupProviderService providerService2;
+
+    protected TestGroupListener listener1 = new TestGroupListener();
+    protected TestGroupListener listener2 = new TestGroupListener();
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private ApplicationId appId;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        groupStore = new SimpleVirtualGroupStore();
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(provider);
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        TestUtils.setField(manager, "coreService", coreService);
+
+        eventDeliveryService = new TestEventDispatcher();
+        injectEventDispatcher(manager, eventDeliveryService);
+
+        appId = new TestApplicationId("VirtualGroupManagerTest");
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(VirtualNetworkGroupStore.class, groupStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        vnet1 = setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = setupVirtualNetworkTopology(manager, TID2);
+
+        groupManager1 = new VirtualNetworkGroupManager(manager, vnet1.id());
+        groupManager2 = new VirtualNetworkGroupManager(manager, vnet2.id());
+        groupManager1.addListener(listener1);
+        groupManager2.addListener(listener2);
+
+        providerService1 = (VirtualGroupProviderService)
+                providerRegistryService.getProviderService(vnet1.id(),
+                                                           VirtualGroupProvider.class);
+        providerService2 = (VirtualGroupProviderService)
+                providerRegistryService.getProviderService(vnet2.id(),
+                                                           VirtualGroupProvider.class);
+    }
+
+    @After
+    public void tearDown() {
+        providerRegistryService.unregisterProvider(provider);
+        assertFalse("provider should not be registered",
+                    providerRegistryService.getProviders().contains(provider.id()));
+        groupManager1.removeListener(listener1);
+        groupManager2.removeListener(listener2);
+
+        manager.deactivate();
+        virtualNetworkManagerStore.deactivate();
+    }
+
+    /**
+     * Tests group creation before the device group AUDIT completes.
+     */
+    @Test
+    public void testGroupServiceBasics() {
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests initial device group AUDIT process.
+     */
+    @Test
+    public void testGroupServiceInitialAudit() {
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+        // Test initial group audit process
+        testInitialAuditWithPendingGroupRequests(vnet1.id(), VDID1);
+        testInitialAuditWithPendingGroupRequests(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests deletion process of any extraneous groups.
+     */
+    @Test
+    public void testGroupServiceAuditExtraneous() {
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+
+        // Test audit with extraneous and missing groups
+        testAuditWithExtraneousMissingGroups(vnet1.id(), VDID1);
+        testAuditWithExtraneousMissingGroups(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests re-apply process of any missing groups tests execution of
+     * any pending group creation request after the device group AUDIT completes
+     * and tests event notifications after receiving confirmation for any
+     * operations from data plane.
+     */
+    @Test
+    public void testGroupServiceAuditConfirmed() {
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+
+        // Test audit with extraneous and missing groups
+        testAuditWithExtraneousMissingGroups(vnet1.id(), VDID1);
+        testAuditWithExtraneousMissingGroups(vnet2.id(), VDID1);
+
+        // Test audit with confirmed groups
+        testAuditWithConfirmedGroups(vnet1.id(), VDID1);
+        testAuditWithConfirmedGroups(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests group Purge Operation.
+     */
+    @Test
+    public void testPurgeGroups() {
+        // Tests for virtual network 1
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+        testAuditWithExtraneousMissingGroups(vnet1.id(), VDID1);
+        // Test group add bucket operations
+        testAddBuckets(vnet1.id(), VDID1);
+        // Test group Purge operations
+        testPurgeGroupEntry(vnet1.id(), VDID1);
+
+        // Tests for virtual network 2
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+        testAuditWithExtraneousMissingGroups(vnet2.id(), VDID1);
+        // Test group add bucket operations
+        testAddBuckets(vnet2.id(), VDID1);
+        // Test group Purge operations
+        testPurgeGroupEntry(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests group bucket modifications (additions and deletions) and
+     * Tests group deletion.
+     */
+    @Test
+    public void testGroupServiceBuckets() {
+        // Tests for virtual network 1
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+
+        testAuditWithExtraneousMissingGroups(vnet1.id(), VDID1);
+        // Test group add bucket operations
+        testAddBuckets(vnet1.id(), VDID1);
+
+        // Test group remove bucket operations
+        testRemoveBuckets(vnet1.id(), VDID1);
+
+        // Test group remove operations
+        testRemoveGroup(vnet1.id(), VDID1);
+
+        // Tests for virtual network 2
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+
+        testAuditWithExtraneousMissingGroups(vnet2.id(), VDID1);
+        // Test group add bucket operations
+        testAddBuckets(vnet2.id(), VDID1);
+
+        // Test group remove bucket operations
+        testRemoveBuckets(vnet2.id(), VDID1);
+
+        // Test group remove operations
+        testRemoveGroup(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests group creation before the device group AUDIT completes with fallback
+     * provider.
+     */
+    @Test
+    public void testGroupServiceFallbackBasics() {
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID2);
+        testGroupCreationBeforeAudit(vnet2.id(), VDID2);
+    }
+
+    // Test Group creation before AUDIT process
+    private void testGroupCreationBeforeAudit(NetworkId networkId, DeviceId deviceId) {
+        PortNumber[] ports1 = {PortNumber.portNumber(31),
+                PortNumber.portNumber(32)};
+        PortNumber[] ports2 = {PortNumber.portNumber(41),
+                PortNumber.portNumber(42)};
+        GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
+        List<GroupBucket> buckets = new ArrayList<>();
+        List<PortNumber> outPorts = new ArrayList<>();
+        outPorts.addAll(Arrays.asList(ports1));
+        outPorts.addAll(Arrays.asList(ports2));
+        for (PortNumber portNumber : outPorts) {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(portNumber)
+                    .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
+                    .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                    .pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(106));
+            buckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+        }
+        GroupBuckets groupBuckets = new GroupBuckets(buckets);
+        GroupDescription newGroupDesc = new DefaultGroupDescription(deviceId,
+                                                                    Group.Type.SELECT,
+                                                                    groupBuckets,
+                                                                    key,
+                                                                    null,
+                                                                    appId);
+        VirtualNetworkGroupManager groupManager;
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+        } else {
+            groupManager = groupManager2;
+        }
+
+        groupManager.addGroup(newGroupDesc);
+        assertEquals(null, groupManager.getGroup(deviceId, key));
+        assertEquals(0, Iterables.size(groupManager.getGroups(deviceId, appId)));
+    }
+
+
+    // Test initial AUDIT process with pending group requests
+    private void testInitialAuditWithPendingGroupRequests(NetworkId networkId,
+                                                          DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+        }
+
+        PortNumber[] ports1 = {PortNumber.portNumber(31),
+                PortNumber.portNumber(32)};
+        PortNumber[] ports2 = {PortNumber.portNumber(41),
+                PortNumber.portNumber(42)};
+        GroupId gId1 = new GroupId(1);
+        Group group1 = createSouthboundGroupEntry(gId1,
+                                                  Arrays.asList(ports1),
+                                                  0, deviceId);
+        GroupId gId2 = new GroupId(2);
+        // Non zero reference count will make the group manager to queue
+        // the extraneous groups until reference count is zero.
+        Group group2 = createSouthboundGroupEntry(gId2,
+                                                  Arrays.asList(ports2),
+                                                  2, deviceId);
+        List<Group> groupEntries = Arrays.asList(group1, group2);
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        // First group metrics would trigger the device audit completion
+        // post which all pending group requests are also executed.
+        GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
+        Group createdGroup = groupManager.getGroup(deviceId, key);
+        int createdGroupId = createdGroup.id().id();
+        assertNotEquals(gId1.id().intValue(), createdGroupId);
+        assertNotEquals(gId2.id().intValue(), createdGroupId);
+
+        List<GroupOperation> expectedGroupOps = Arrays.asList(
+                GroupOperation.createDeleteGroupOperation(gId1,
+                                                          Group.Type.SELECT),
+                GroupOperation.createAddGroupOperation(
+                        createdGroup.id(),
+                        Group.Type.SELECT,
+                        createdGroup.buckets()));
+        if (deviceId.equals(VDID1)) {
+            provider.validate(networkId, deviceId, expectedGroupOps);
+        }
+    }
+
+    // Test AUDIT process with extraneous groups and missing groups
+    private void testAuditWithExtraneousMissingGroups(NetworkId networkId,
+                                                      DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+        }
+
+        PortNumber[] ports1 = {PortNumber.portNumber(31),
+                PortNumber.portNumber(32)};
+        PortNumber[] ports2 = {PortNumber.portNumber(41),
+                PortNumber.portNumber(42)};
+        GroupId gId1 = new GroupId(1);
+        Group group1 = createSouthboundGroupEntry(gId1,
+                                                  Arrays.asList(ports1),
+                                                  0, deviceId);
+        GroupId gId2 = new GroupId(2);
+        Group group2 = createSouthboundGroupEntry(gId2,
+                                                  Arrays.asList(ports2),
+                                                  0, deviceId);
+        List<Group> groupEntries = Arrays.asList(group1, group2);
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
+        Group createdGroup = groupManager.getGroup(deviceId, key);
+        List<GroupOperation> expectedGroupOps = Arrays.asList(
+                GroupOperation.createDeleteGroupOperation(gId1,
+                                                          Group.Type.SELECT),
+                GroupOperation.createDeleteGroupOperation(gId2,
+                                                          Group.Type.SELECT),
+                GroupOperation.createAddGroupOperation(createdGroup.id(),
+                                                       Group.Type.SELECT,
+                                                       createdGroup.buckets()));
+        if (deviceId.equals(VDID1)) {
+            provider.validate(networkId, deviceId, expectedGroupOps);
+        }
+    }
+
+    // Test AUDIT with confirmed groups
+    private void testAuditWithConfirmedGroups(NetworkId networkId,
+                                              DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        TestGroupListener listener;
+
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+            listener = listener1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+            listener = listener2;
+        }
+
+        GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
+        Group createdGroup = groupManager.getGroup(deviceId, key);
+        createdGroup = new DefaultGroup(createdGroup.id(),
+                                        deviceId,
+                                        Group.Type.SELECT,
+                                        createdGroup.buckets());
+        List<Group> groupEntries = Collections.singletonList(createdGroup);
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        listener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADDED));
+    }
+
+    private Group createSouthboundGroupEntry(GroupId gId,
+                                             List<PortNumber> ports,
+                                             long referenceCount, DeviceId deviceId) {
+        List<PortNumber> outPorts = new ArrayList<>();
+        outPorts.addAll(ports);
+
+        List<GroupBucket> buckets = new ArrayList<>();
+        for (PortNumber portNumber : outPorts) {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(portNumber)
+                    .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
+                    .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                    .pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(106));
+            buckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+        }
+        GroupBuckets groupBuckets = new GroupBuckets(buckets);
+        StoredGroupEntry group = new DefaultGroup(
+                gId, deviceId, Group.Type.SELECT, groupBuckets);
+        group.setReferenceCount(referenceCount);
+        return group;
+    }
+
+    // Test group add bucket operations
+    private void testAddBuckets(NetworkId networkId, DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        TestGroupListener listener;
+
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+            listener = listener1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+            listener = listener2;
+        }
+
+        GroupKey addKey = new DefaultGroupKey("group1AddBuckets".getBytes());
+
+        GroupKey prevKey = new DefaultGroupKey("group1BeforeAudit".getBytes());
+        Group createdGroup = groupManager.getGroup(deviceId, prevKey);
+        List<GroupBucket> buckets = new ArrayList<>();
+        buckets.addAll(createdGroup.buckets().buckets());
+
+        PortNumber[] addPorts = {PortNumber.portNumber(51),
+                PortNumber.portNumber(52)};
+        List<PortNumber> outPorts;
+        outPorts = new ArrayList<>();
+        outPorts.addAll(Arrays.asList(addPorts));
+        List<GroupBucket> addBuckets;
+        addBuckets = new ArrayList<>();
+        for (PortNumber portNumber : outPorts) {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(portNumber)
+                    .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
+                    .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                    .pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(106));
+            addBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+            buckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+        }
+        GroupBuckets groupAddBuckets = new GroupBuckets(addBuckets);
+        groupManager.addBucketsToGroup(deviceId,
+                                       prevKey,
+                                       groupAddBuckets,
+                                       addKey,
+                                       appId);
+        GroupBuckets updatedBuckets = new GroupBuckets(buckets);
+        List<GroupOperation> expectedGroupOps = Collections.singletonList(
+                GroupOperation.createModifyGroupOperation(createdGroup.id(),
+                                                          Group.Type.SELECT,
+                                                          updatedBuckets));
+        if (deviceId.equals(VDID1)) {
+            provider.validate(networkId, deviceId, expectedGroupOps);
+        }
+
+        Group existingGroup = groupManager.getGroup(deviceId, addKey);
+        List<Group> groupEntries = Collections.singletonList(existingGroup);
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        listener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
+    }
+
+    // Test purge group entry operations
+    private void testPurgeGroupEntry(NetworkId networkId, DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+        } else {
+            groupManager = groupManager2;
+        }
+
+        assertEquals(1, Iterables.size(groupManager.getGroups(deviceId, appId)));
+        groupManager.purgeGroupEntries(deviceId);
+        assertEquals(0, Iterables.size(groupManager.getGroups(deviceId, appId)));
+    }
+
+    // Test group remove bucket operations
+    private void testRemoveBuckets(NetworkId networkId, DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        TestGroupListener listener;
+
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+            listener = listener1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+            listener = listener2;
+        }
+
+        GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
+
+        GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes());
+        Group createdGroup = groupManager.getGroup(deviceId, prevKey);
+        List<GroupBucket> buckets = new ArrayList<>();
+        buckets.addAll(createdGroup.buckets().buckets());
+
+        PortNumber[] removePorts = {PortNumber.portNumber(31),
+                PortNumber.portNumber(32)};
+        List<PortNumber> outPorts = new ArrayList<>();
+        outPorts.addAll(Arrays.asList(removePorts));
+        List<GroupBucket> removeBuckets = new ArrayList<>();
+        for (PortNumber portNumber : outPorts) {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(portNumber)
+                    .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
+                    .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                    .pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(106));
+            removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+            buckets.remove(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+        }
+        GroupBuckets groupRemoveBuckets = new GroupBuckets(removeBuckets);
+        groupManager.removeBucketsFromGroup(deviceId,
+                                            prevKey,
+                                            groupRemoveBuckets,
+                                            removeKey,
+                                            appId);
+        GroupBuckets updatedBuckets = new GroupBuckets(buckets);
+        List<GroupOperation> expectedGroupOps = Collections.singletonList(
+                GroupOperation.createModifyGroupOperation(createdGroup.id(),
+                                                          Group.Type.SELECT,
+                                                          updatedBuckets));
+        if (deviceId.equals(VDID1)) {
+            provider.validate(networkId, deviceId, expectedGroupOps);
+        }
+
+        Group existingGroup = groupManager.getGroup(deviceId, removeKey);
+        List<Group> groupEntries = Collections.singletonList(existingGroup);
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        listener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
+    }
+
+    // Test group remove operations
+    private void testRemoveGroup(NetworkId networkId, DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        TestGroupListener listener;
+
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+            listener = listener1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+            listener = listener2;
+        }
+
+        GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
+        Group existingGroup = groupManager.getGroup(deviceId, currKey);
+        groupManager.removeGroup(deviceId, currKey, appId);
+        List<GroupOperation> expectedGroupOps = Collections.singletonList(
+                GroupOperation.createDeleteGroupOperation(existingGroup.id(),
+                                                          Group.Type.SELECT));
+        if (deviceId.equals(VDID1)) {
+            provider.validate(networkId, deviceId, expectedGroupOps);
+        }
+
+        List<Group> groupEntries = Collections.emptyList();
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        listener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVED));
+    }
+
+    private class TestGroupProvider extends AbstractVirtualProvider
+            implements VirtualGroupProvider {
+        NetworkId lastNetworkId;
+        DeviceId lastDeviceId;
+        List<GroupOperation> groupOperations = new ArrayList<>();
+
+        protected TestGroupProvider() {
+            super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
+        }
+
+        @Override
+        public void performGroupOperation(NetworkId networkId, DeviceId deviceId,
+                                          GroupOperations groupOps) {
+            lastNetworkId = networkId;
+            lastDeviceId = deviceId;
+            groupOperations.addAll(groupOps.operations());
+        }
+
+        public void validate(NetworkId expectedNetworkId, DeviceId expectedDeviceId,
+                             List<GroupOperation> expectedGroupOps) {
+            if (expectedGroupOps == null) {
+                assertTrue("events generated", groupOperations.isEmpty());
+                return;
+            }
+
+            assertEquals(lastNetworkId, expectedNetworkId);
+            assertEquals(lastDeviceId, expectedDeviceId);
+            assertTrue((this.groupOperations.containsAll(expectedGroupOps) &&
+                    expectedGroupOps.containsAll(groupOperations)));
+
+            groupOperations.clear();
+            lastDeviceId = null;
+            lastNetworkId = null;
+        }
+    }
+
+    private static class TestGroupListener implements GroupListener {
+        final List<GroupEvent> events = new ArrayList<>();
+
+        @Override
+        public void event(GroupEvent event) {
+            events.add(event);
+        }
+
+        public void validateEvent(List<GroupEvent.Type> expectedEvents) {
+            int i = 0;
+            System.err.println("events :" + events);
+            for (GroupEvent e : events) {
+                assertEquals("unexpected event", expectedEvents.get(i), e.type());
+                i++;
+            }
+            assertEquals("mispredicted number of events",
+                         expectedEvents.size(), events.size());
+            events.clear();
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManagerTest.java
new file mode 100644
index 0000000..e60d343
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManagerTest.java
@@ -0,0 +1,285 @@
+/*
+ * 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 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.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.TestDeviceParams;
+import org.onosproject.net.host.HostService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import static org.junit.Assert.*;
+
+/**
+ * Junit tests for VirtualNetworkHostService.
+ */
+public class VirtualNetworkHostManagerTest extends TestDeviceParams {
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private TestServiceDirectory testDirectory;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+    }
+
+    /**
+     * Sets up a virtual network with hosts.
+     *
+     * @return virtual network
+     */
+    private VirtualNetwork setupVnet() {
+        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);
+
+        ConnectPoint hostCp1 = new ConnectPoint(DID1, P1);
+        ConnectPoint hostCp2 = new ConnectPoint(DID2, P2);
+        manager.createVirtualPort(virtualNetwork.id(), hostCp1.deviceId(), hostCp1.port(),
+                new ConnectPoint(virtualDevice1.id(), hostCp1.port()));
+        manager.createVirtualPort(virtualNetwork.id(), hostCp2.deviceId(), hostCp2.port(),
+                new ConnectPoint(virtualDevice2.id(), hostCp2.port()));
+
+        manager.createVirtualHost(virtualNetwork.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+        manager.createVirtualHost(virtualNetwork.id(), HID2, MAC2, VLAN2, LOC2, IPSET2);
+        return virtualNetwork;
+    }
+
+    /**
+     * Sets up a virtual network with no hosts.
+     *
+     * @return virtual network
+     */
+    private VirtualNetwork setupEmptyVnet() {
+        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);
+
+        ConnectPoint hostCp1 = new ConnectPoint(DID1, P1);
+        ConnectPoint hostCp2 = new ConnectPoint(DID2, P2);
+        manager.createVirtualPort(virtualNetwork.id(), hostCp1.deviceId(), hostCp1.port(),
+                new ConnectPoint(virtualDevice1.id(), hostCp1.port()));
+        manager.createVirtualPort(virtualNetwork.id(), hostCp2.deviceId(), hostCp2.port(),
+                new ConnectPoint(virtualDevice2.id(), hostCp2.port()));
+
+        return virtualNetwork;
+    }
+
+    /**
+     * Tests the getHosts(), getHost(), getHostsByXX(), getConnectedHosts() methods
+     * on a non-empty virtual network.
+     */
+    @Test
+    public void testGetHostsOnNonEmptyVnet() {
+        VirtualNetwork virtualNetwork = setupEmptyVnet();
+        VirtualHost vhost1 = manager.createVirtualHost(virtualNetwork.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+        VirtualHost vhost2 = manager.createVirtualHost(virtualNetwork.id(), HID2, MAC2, VLAN2, LOC2, IPSET2);
+        HostService hostService = manager.get(virtualNetwork.id(), HostService.class);
+
+        // test the getHosts() and getHostCount() methods
+        Iterator<Host> itHosts = hostService.getHosts().iterator();
+        assertEquals("The host set size did not match.", 2, Iterators.size(itHosts));
+        assertEquals("The host count did not match.", 2, hostService.getHostCount());
+
+        // test the getHost() method
+        Host testHost = hostService.getHost(HID2);
+        assertEquals("The expected host did not match.", vhost2, testHost);
+
+        // test the getHostsByVlan(...) method
+        Collection<Host> collHost = hostService.getHostsByVlan(VLAN1);
+        assertEquals("The host set size did not match.", 1, collHost.size());
+        assertTrue("The host did not match.", collHost.contains(vhost1));
+
+        // test the getHostsByMac(...) method
+        collHost = hostService.getHostsByMac(MAC2);
+        assertEquals("The host set size did not match.", 1, collHost.size());
+        assertTrue("The host did not match.", collHost.contains(vhost2));
+
+        // test the getHostsByIp(...) method
+        collHost = hostService.getHostsByIp(IP1);
+        assertEquals("The host set size did not match.", 2, collHost.size());
+        collHost = hostService.getHostsByIp(IP2);
+        assertEquals("The host set size did not match.", 1, collHost.size());
+        assertTrue("The host did not match.", collHost.contains(vhost1));
+
+        // test the getConnectedHosts(ConnectPoint) method
+        collHost = hostService.getConnectedHosts(LOC1);
+        assertEquals("The host set size did not match.", 1, collHost.size());
+        assertTrue("The host did not match.", collHost.contains(vhost1));
+
+        // test the getConnectedHosts(DeviceId) method
+        collHost = hostService.getConnectedHosts(DID2);
+        assertEquals("The host set size did not match.", 1, collHost.size());
+        assertTrue("The host did not match.", collHost.contains(vhost2));
+    }
+
+    /**
+     * Tests the getHosts(), getHost(), getHostsByXX(), getConnectedHosts() methods
+     * on an empty virtual network.
+     */
+    @Test
+    public void testGetHostsOnEmptyVnet() {
+        VirtualNetwork virtualNetwork = setupEmptyVnet();
+        HostService hostService = manager.get(virtualNetwork.id(), HostService.class);
+
+        // test the getHosts() and getHostCount() methods
+        Iterator<Host> itHosts = hostService.getHosts().iterator();
+        assertEquals("The host set size did not match.", 0, Iterators.size(itHosts));
+        assertEquals("The host count did not match.", 0, hostService.getHostCount());
+
+        // test the getHost() method
+        Host testHost = hostService.getHost(HID2);
+        assertNull("The host should be null.", testHost);
+
+        // test the getHostsByVlan(...) method
+        Collection<Host> collHost = hostService.getHostsByVlan(VLAN1);
+        assertEquals("The host set size did not match.", 0, collHost.size());
+
+        // test the getHostsByMac(...) method
+        collHost = hostService.getHostsByMac(MAC2);
+        assertEquals("The host set size did not match.", 0, collHost.size());
+
+        // test the getHostsByIp(...) method
+        collHost = hostService.getHostsByIp(IP1);
+        assertEquals("The host set size did not match.", 0, collHost.size());
+
+        // test the getConnectedHosts(ConnectPoint) method
+        collHost = hostService.getConnectedHosts(LOC1);
+        assertEquals("The host set size did not match.", 0, collHost.size());
+
+        // test the getConnectedHosts(DeviceId) method
+        collHost = hostService.getConnectedHosts(DID2);
+        assertEquals("The host set size did not match.", 0, collHost.size());
+    }
+
+    /**
+     * Tests querying for a host using a null host identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetHostByNullId() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getHost(null);
+    }
+
+    /**
+     * Tests querying for hosts with null mac.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetHostsByNullMac() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getHostsByMac(null);
+    }
+
+    /**
+     * Tests querying for hosts with null vlan.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetHostsByNullVlan() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getHostsByVlan(null);
+    }
+
+    /**
+     * Tests querying for hosts with null ip.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetHostsByNullIp() {
+        VirtualNetwork vnet = setupVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getHostsByIp(null);
+    }
+
+    /**
+     * Tests querying for connected hosts with null host location (connect point).
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetConnectedHostsByNullLoc() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getConnectedHosts((ConnectPoint) null);
+    }
+
+    /**
+     * Tests querying for connected hosts with null device id.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetConnectedHostsByNullDeviceId() {
+        VirtualNetwork vnet = setupVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getConnectedHosts((DeviceId) null);
+    }
+
+}
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);
+//    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManagerTest.java
new file mode 100644
index 0000000..2805f9e
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManagerTest.java
@@ -0,0 +1,326 @@
+/*
+ * 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 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.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.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.link.LinkService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+/**
+ * Junit tests for VirtualNetworkLinkService.
+ */
+public class VirtualNetworkLinkManagerTest extends TestDeviceParams {
+
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService;
+    private TestServiceDirectory testDirectory;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        coreService = new VirtualNetworkLinkManagerTest.TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+    }
+
+    /**
+     * Tests the getLinks(), getActiveLinks(), getLinkCount(), getLink(),
+     * getLinks(ConnectPoint), getDeviceLinks(), getDeviceEgressLinks(), getDeviceIngressLinks(),
+     * getEgressLinks(), getIngressLinks() methods.
+     */
+    @Test
+    public void testGetLinks() {
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), src.deviceId(), src.port(),
+                                  new ConnectPoint(srcVirtualDevice.id(), src.port()));
+
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), dst.deviceId(), dst.port(),
+                                  new ConnectPoint(dstVirtualDevice.id(), dst.port()));
+
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), src, dst);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), dst, src);
+
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getLinks() method
+        Iterator<Link> it = linkService.getLinks().iterator();
+        assertEquals("The link set size did not match.", 2, Iterators.size(it));
+
+        // test the getActiveLinks() method where all links are INACTIVE
+        Iterator<Link> it2 = linkService.getActiveLinks().iterator();
+        assertEquals("The link set size did not match.", 0, Iterators.size(it2));
+
+        // test the getActiveLinks() method where one link is ACTIVE
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        Iterator<Link> it3 = linkService.getActiveLinks().iterator();
+        assertEquals("The link set size did not match.", 1, Iterators.size(it3));
+
+        // test the getLinkCount() method
+        assertEquals("The link set size did not match.", 2, linkService.getLinkCount());
+
+        // test the getLink() method
+        assertEquals("The expect link did not match.", link1,
+                     linkService.getLink(src, dst));
+        assertEquals("The expect link did not match.", link2,
+                     linkService.getLink(dst, src));
+        assertNotEquals("The expect link should not have matched.", link1,
+                        linkService.getLink(dst, src));
+
+        // test the getLinks(ConnectPoint) method
+        assertEquals("The link set size did not match.", 2, linkService.getLinks(src).size());
+        assertEquals("The link set size did not match.", 2, linkService.getLinks(dst).size());
+        ConnectPoint connectPoint = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(3));
+        assertEquals("The link set size did not match.", 0, linkService.getLinks(connectPoint).size());
+
+        // test the getDeviceLinks() method
+        assertEquals("The link set size did not match.", 2,
+                     linkService.getDeviceLinks(DID1).size());
+        assertEquals("The link set size did not match.", 2,
+                     linkService.getDeviceLinks(DID2).size());
+        assertEquals("The link set size did not match.", 0,
+                     linkService.getDeviceLinks(DID3).size());
+
+        // test the getDeviceEgressLinks() method
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getDeviceEgressLinks(DID1).size());
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getDeviceEgressLinks(DID2).size());
+        assertEquals("The link set size did not match.", 0,
+                     linkService.getDeviceEgressLinks(DID3).size());
+
+        // test the getDeviceIngressLinks() method
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getDeviceIngressLinks(DID1).size());
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getDeviceIngressLinks(DID2).size());
+        assertEquals("The link set size did not match.", 0,
+                     linkService.getDeviceIngressLinks(DID3).size());
+
+        // test the getEgressLinks() method
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getEgressLinks(src).size());
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getEgressLinks(dst).size());
+        assertEquals("The link set size did not match.", 0,
+                     linkService.getEgressLinks(connectPoint).size());
+
+        // test the getIngressLinks() method
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getIngressLinks(src).size());
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getIngressLinks(dst).size());
+        assertEquals("The link set size did not match.", 0,
+                     linkService.getIngressLinks(connectPoint).size());
+    }
+
+    /**
+     * Tests the getLink() method using a null src connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetLinkByNullSrc() {
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualLink(virtualNetwork.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork.id(), dst, src);
+
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getLink() method with a null src connect point.
+        linkService.getLink(null, dst);
+    }
+
+    /**
+     * Tests the getLink() method using a null dst connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetLinkByNullDst() {
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualLink(virtualNetwork.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork.id(), dst, src);
+
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getLink() method with a null dst connect point.
+        linkService.getLink(src, null);
+    }
+
+    /**
+     * Tests querying for links using a null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDeviceLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getDeviceLinks() method with a null device identifier.
+        linkService.getDeviceLinks(null);
+    }
+
+    /**
+     * Tests querying for links using a null connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getLinks() method with a null connect point.
+        linkService.getLinks(null);
+    }
+
+    /**
+     * Tests querying for device egress links using a null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDeviceEgressLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getDeviceEgressLinks() method with a null device identifier.
+        linkService.getDeviceEgressLinks(null);
+    }
+
+    /**
+     * Tests querying for device ingress links using a null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDeviceIngressLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getDeviceIngressLinks() method with a null device identifier.
+        linkService.getDeviceIngressLinks(null);
+    }
+
+    /**
+     * Tests querying for egress links using a null connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetEgressLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getEgressLinks() method with a null connect point.
+        linkService.getEgressLinks(null);
+    }
+
+    /**
+     * Tests querying for ingress links using a null connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetIngressLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getIngressLinks() method with a null connect point.
+        linkService.getIngressLinks(null);
+    }
+
+    /**
+     * 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/VirtualNetworkManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
new file mode 100644
index 0000000..9156c38
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
@@ -0,0 +1,1003 @@
+/*
+ * 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.Lists;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestTools;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ClusterServiceAdapter;
+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.event.EventDeliveryService;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+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.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkGroupStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntentStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkListener;
+import org.onosproject.incubator.net.virtual.VirtualNetworkPacketStore;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.incubator.net.virtual.impl.provider.DefaultVirtualFlowRuleProvider;
+import org.onosproject.incubator.net.virtual.impl.provider.DefaultVirtualGroupProvider;
+import org.onosproject.incubator.net.virtual.impl.provider.DefaultVirtualNetworkProvider;
+import org.onosproject.incubator.net.virtual.impl.provider.DefaultVirtualPacketProvider;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowRuleStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualGroupStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualIntentStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualPacketStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MockIdGenerator;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.*;
+import static org.onosproject.net.NetTestTools.APP_ID;
+
+/**
+ * Junit tests for VirtualNetworkManager.
+ */
+public class VirtualNetworkManagerTest extends VirtualNetworkTestUtil {
+    private final String tenantIdValue1 = "TENANT_ID1";
+    private final String tenantIdValue2 = "TENANT_ID2";
+
+    private VirtualNetworkManager manager;
+    private DefaultVirtualNetworkProvider topologyProvider;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService;
+    private TestListener listener = new TestListener();
+    private TopologyService topologyService;
+
+    private ConnectPoint cp6;
+    private ConnectPoint cp7;
+
+    private TestServiceDirectory testDirectory;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+        MockIdGenerator.cleanBind();
+
+        coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService",
+                           new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.addListener(listener);
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.removeListener(listener);
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+        MockIdGenerator.cleanBind();
+    }
+
+    /**
+     * Tests registering a null tenant id.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testRegisterNullTenantId() {
+        manager.registerTenantId(null);
+    }
+
+    /**
+     * Tests registering/unregistering a tenant id.
+     */
+    @Test
+    public void testRegisterUnregisterTenantId() {
+        manager.unregisterTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue2));
+        Collection<TenantId> tenantIdCollection = manager.getTenantIds();
+        assertEquals("The tenantId set size did not match.", 2, tenantIdCollection.size());
+
+        manager.unregisterTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.unregisterTenantId(TenantId.tenantId(tenantIdValue2));
+        tenantIdCollection = manager.getTenantIds();
+        assertTrue("The tenantId set should be empty.", tenantIdCollection.isEmpty());
+
+        // Validate that the events were all received in the correct order.
+        validateEvents(VirtualNetworkEvent.Type.TENANT_REGISTERED,
+                       VirtualNetworkEvent.Type.TENANT_REGISTERED,
+                       VirtualNetworkEvent.Type.TENANT_UNREGISTERED,
+                       VirtualNetworkEvent.Type.TENANT_UNREGISTERED);
+    }
+
+    /**
+     * Test method {@code getTenantId()} for registered virtual network.
+     */
+    @Test
+    public void testGetTenantIdForRegisteredVirtualNetwork() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(tenantIdValue1);
+        TenantId tenantId = manager.getTenantId(virtualNetwork.id());
+
+        assertThat(tenantId.toString(), is(tenantIdValue1));
+    }
+
+    /**
+     * Test method {@code getTenantId()} for null virtual network id.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetTenantIdForNullVirtualNetwork() {
+        manager.getTenantId(null);
+    }
+
+    /**
+     * Test method {@code getVirtualNetwork()} for registered virtual network.
+     */
+    @Test
+    public void testGetVirtualNetworkForRegisteredNetwork() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(tenantIdValue1);
+
+        assertNotNull("Registered virtual network is null", manager.getVirtualNetwork(virtualNetwork.id()));
+    }
+
+    /**
+     * Test method {@code getVirtualNetwork()} for null virtual network id.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetVirtualForNullVirtualNetworkId() {
+        manager.getVirtualNetwork(null);
+    }
+
+    /**
+     * Tests adding a null virtual network.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testCreateNullVirtualNetwork() {
+        manager.createVirtualNetwork(null);
+    }
+
+    /**
+     * Tests removal of a virtual network twice.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testRemoveVnetTwice() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        manager.removeVirtualNetwork(virtualNetwork.id());
+        manager.removeVirtualNetwork(virtualNetwork.id());
+    }
+
+    /**
+     * Tests add and remove of virtual networks.
+     */
+    @Test
+    public void testAddRemoveVirtualNetwork() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        Set<VirtualNetwork> virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
+        assertNotNull("The virtual network set should not be null", virtualNetworks);
+        assertEquals("The virtual network set size did not match.", 2, virtualNetworks.size());
+
+        int remaining = virtualNetworks.size();
+        for (VirtualNetwork virtualNetwork : virtualNetworks) {
+            manager.removeVirtualNetwork(virtualNetwork.id());
+            assertEquals("The expected virtual network size does not match",
+                         --remaining, manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1)).size());
+        }
+        virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
+        assertTrue("The virtual network set should be empty.", virtualNetworks.isEmpty());
+
+        // Create/remove a virtual network.
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        manager.removeVirtualNetwork(virtualNetwork.id());
+
+        virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
+        assertTrue("The virtual network set should be empty.", virtualNetworks.isEmpty());
+
+        // Validate that the events were all received in the correct order.
+        validateEvents(VirtualNetworkEvent.Type.TENANT_REGISTERED,
+                       VirtualNetworkEvent.Type.NETWORK_ADDED,
+                       VirtualNetworkEvent.Type.NETWORK_ADDED,
+                       VirtualNetworkEvent.Type.NETWORK_REMOVED,
+                       VirtualNetworkEvent.Type.NETWORK_REMOVED,
+                       VirtualNetworkEvent.Type.NETWORK_ADDED,
+                       VirtualNetworkEvent.Type.NETWORK_REMOVED);
+    }
+
+    /**
+     * Tests adding a null virtual device.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testCreateNullVirtualDevice() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        manager.createVirtualDevice(virtualNetwork.id(), null);
+    }
+
+    /**
+     * Tests adding a virtual device where no virtual network exists.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testCreateVirtualDeviceWithNoNetwork() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork =
+                new DefaultVirtualNetwork(NetworkId.NONE,
+                                          TenantId.tenantId(tenantIdValue1));
+
+        manager.createVirtualDevice(virtualNetwork.id(), DID1);
+    }
+
+    /**
+     * Tests add and remove of virtual devices.
+     */
+    @Test
+    public void testAddRemoveVirtualDevice() {
+        List<VirtualNetworkEvent.Type> expectedEventTypes = new ArrayList<>();
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        expectedEventTypes.add(VirtualNetworkEvent.Type.TENANT_REGISTERED);
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        expectedEventTypes.add(VirtualNetworkEvent.Type.NETWORK_ADDED);
+        VirtualNetwork virtualNetwork2 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        expectedEventTypes.add(VirtualNetworkEvent.Type.NETWORK_ADDED);
+        manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_ADDED);
+        manager.createVirtualDevice(virtualNetwork2.id(), DID2);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_ADDED);
+
+        Set<VirtualDevice> virtualDevices1 = manager.getVirtualDevices(virtualNetwork1.id());
+        assertNotNull("The virtual device set should not be null", virtualDevices1);
+        assertEquals("The virtual device set size did not match.", 1, virtualDevices1.size());
+
+        Set<VirtualDevice> virtualDevices2 = manager.getVirtualDevices(virtualNetwork2.id());
+        assertNotNull("The virtual device set should not be null", virtualDevices2);
+        assertEquals("The virtual device set size did not match.", 1, virtualDevices2.size());
+
+        for (VirtualDevice virtualDevice : virtualDevices1) {
+            manager.removeVirtualDevice(virtualNetwork1.id(), virtualDevice.id());
+            expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_REMOVED);
+            // attempt to remove the same virtual device again - no event expected.
+            manager.removeVirtualDevice(virtualNetwork1.id(), virtualDevice.id());
+        }
+        virtualDevices1 = manager.getVirtualDevices(virtualNetwork1.id());
+        assertTrue("The virtual device set should be empty.", virtualDevices1.isEmpty());
+
+        // Add/remove the virtual device again.
+        VirtualDevice virtualDevice = manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_ADDED);
+        manager.removeVirtualDevice(virtualDevice.networkId(), virtualDevice.id());
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_REMOVED);
+        virtualDevices1 = manager.getVirtualDevices(virtualNetwork1.id());
+        assertTrue("The virtual device set should be empty.", virtualDevices1.isEmpty());
+
+        // Validate that the events were all received in the correct order.
+        validateEvents(expectedEventTypes.toArray(
+                new VirtualNetworkEvent.Type[expectedEventTypes.size()]));
+    }
+
+    /**
+     * Tests getting a collection of physical device identifier corresponding to
+     * the specified virtual device.
+     */
+    @Test
+    public void testGetPhysicalDevices() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue2));
+
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork2 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue2));
+
+        // two virtual device in first virtual network
+        VirtualDevice vDevice1InVnet1 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        VirtualDevice vDevice2InVnet1 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID2);
+        // Two virtual device in second virtual network
+        VirtualDevice vDevice1InVnet2 =
+                manager.createVirtualDevice(virtualNetwork2.id(), DID1);
+        VirtualDevice vDevice2InVnet2 =
+                manager.createVirtualDevice(virtualNetwork2.id(), DID2);
+
+        // Connection Point from each physical device
+        // Virtual network 1
+        ConnectPoint cp1InVnet1 =
+                new ConnectPoint(PHYDID1, PortNumber.portNumber(10));
+        ConnectPoint cp2InVnet1 =
+                new ConnectPoint(PHYDID2, PortNumber.portNumber(20));
+        ConnectPoint cp3InVnet1 =
+                new ConnectPoint(PHYDID3, PortNumber.portNumber(30));
+        ConnectPoint cp4InVnet1 =
+                new ConnectPoint(PHYDID4, PortNumber.portNumber(40));
+        // Virtual network 2
+        ConnectPoint cp1InVnet2 =
+                new ConnectPoint(PHYDID1, PortNumber.portNumber(10));
+        ConnectPoint cp2InVnet2 =
+                new ConnectPoint(PHYDID2, PortNumber.portNumber(20));
+        ConnectPoint cp3InVnet2 =
+                new ConnectPoint(PHYDID3, PortNumber.portNumber(30));
+        ConnectPoint cp4InVnet2 =
+                new ConnectPoint(PHYDID4, PortNumber.portNumber(40));
+
+        // Make simple BigSwitch by mapping two phyDevice to one vDevice
+        // First vDevice in first virtual network
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice1InVnet1.id(), PortNumber.portNumber(1), cp1InVnet1);
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice1InVnet1.id(), PortNumber.portNumber(2), cp2InVnet1);
+        // Second vDevice in first virtual network
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice2InVnet1.id(), PortNumber.portNumber(1), cp3InVnet1);
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice2InVnet1.id(), PortNumber.portNumber(2), cp4InVnet1);
+        // First vDevice in second virtual network
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice1InVnet2.id(), PortNumber.portNumber(1), cp1InVnet2);
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice1InVnet2.id(), PortNumber.portNumber(2), cp2InVnet2);
+        // Second vDevice in second virtual network
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice2InVnet2.id(), PortNumber.portNumber(1), cp3InVnet2);
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice2InVnet2.id(), PortNumber.portNumber(2), cp4InVnet2);
+
+
+        Set<DeviceId> physicalDeviceSet;
+        Set<DeviceId> testSet = new HashSet<>();
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork1.id(), vDevice1InVnet1.id());
+        testSet.add(PHYDID1);
+        testSet.add(PHYDID2);
+        assertEquals("The physical devices 1 did not match", testSet, physicalDeviceSet);
+        testSet.clear();
+
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork1.id(), vDevice2InVnet1.id());
+        testSet.add(PHYDID3);
+        testSet.add(PHYDID4);
+        assertEquals("The physical devices 2 did not match", testSet, physicalDeviceSet);
+        testSet.clear();
+
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork2.id(), vDevice1InVnet2.id());
+        testSet.add(PHYDID1);
+        testSet.add(PHYDID2);
+        assertEquals("The physical devices 1 did not match", testSet, physicalDeviceSet);
+        testSet.clear();
+
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork2.id(), vDevice2InVnet2.id());
+        testSet.add(PHYDID3);
+        testSet.add(PHYDID4);
+        assertEquals("The physical devices 2 did not match", testSet, physicalDeviceSet);
+        testSet.clear();
+    }
+
+    /**
+     * Tests adding a null virtual host.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testCreateNullVirtualHost() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        manager.createVirtualHost(virtualNetwork.id(), null, null, null, null, null);
+    }
+
+    /**
+     * Tests adding a virtual host where no virtual network exists.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testCreateVirtualHostWithNoNetwork() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork =
+                new DefaultVirtualNetwork(NetworkId.NONE, TenantId.tenantId(tenantIdValue1));
+
+        manager.createVirtualHost(virtualNetwork.id(), HID1, null, null, null, null);
+    }
+
+    /**
+     * Tests adding a virtual host where no virtual port exists.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testCreateVirtualHostWithNoVirtualPort() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        manager.createVirtualHost(virtualNetwork1.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+    }
+
+    /**
+     * Tests add and remove of virtual hosts.
+     */
+    @Test
+    public void testAddRemoveVirtualHost() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork2 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork2.id(), DID2);
+
+        ConnectPoint hostCp1 = new ConnectPoint(DID1, P1);
+        ConnectPoint hostCp2 = new ConnectPoint(DID2, P2);
+        manager.createVirtualPort(virtualNetwork1.id(), hostCp1.deviceId(), hostCp1.port(),
+                new ConnectPoint(virtualDevice1.id(), hostCp1.port()));
+        manager.createVirtualPort(virtualNetwork2.id(), hostCp2.deviceId(), hostCp2.port(),
+                new ConnectPoint(virtualDevice2.id(), hostCp2.port()));
+
+        manager.createVirtualHost(virtualNetwork1.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+        manager.createVirtualHost(virtualNetwork2.id(), HID2, MAC2, VLAN2, LOC2, IPSET2);
+
+        Set<VirtualHost> virtualHosts1 = manager.getVirtualHosts(virtualNetwork1.id());
+        assertNotNull("The virtual host set should not be null", virtualHosts1);
+        assertEquals("The virtual host set size did not match.", 1, virtualHosts1.size());
+
+        Set<VirtualHost> virtualHosts2 = manager.getVirtualHosts(virtualNetwork2.id());
+        assertNotNull("The virtual host set should not be null", virtualHosts2);
+        assertEquals("The virtual host set size did not match.", 1, virtualHosts2.size());
+
+        for (VirtualHost virtualHost : virtualHosts1) {
+            manager.removeVirtualHost(virtualNetwork1.id(), virtualHost.id());
+            // attempt to remove the same virtual host again.
+            manager.removeVirtualHost(virtualNetwork1.id(), virtualHost.id());
+        }
+        virtualHosts1 = manager.getVirtualHosts(virtualNetwork1.id());
+        assertTrue("The virtual host set should be empty.", virtualHosts1.isEmpty());
+
+        // Add/remove the virtual host again.
+        VirtualHost virtualHost =
+                manager.createVirtualHost(virtualNetwork1.id(),
+                                          HID1, MAC1, VLAN1, LOC1, IPSET1);
+        manager.removeVirtualHost(virtualHost.networkId(), virtualHost.id());
+        virtualHosts1 = manager.getVirtualHosts(virtualNetwork1.id());
+        assertTrue("The virtual host set should be empty.", virtualHosts1.isEmpty());
+    }
+
+    /**
+     * Tests add and remove of virtual links.
+     */
+    @Test
+    public void testAddRemoveVirtualLink() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID2);
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork1.id(), src.deviceId(), src.port(),
+                                  new ConnectPoint(srcVirtualDevice.id(), src.port()));
+
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork1.id(), dst.deviceId(), dst.port(),
+                                  new ConnectPoint(dstVirtualDevice.id(), dst.port()));
+
+        manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork1.id(), dst, src);
+
+        Set<VirtualLink> virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+        assertNotNull("The virtual link set should not be null", virtualLinks);
+        assertEquals("The virtual link set size did not match.", 2, virtualLinks.size());
+
+        for (VirtualLink virtualLink : virtualLinks) {
+            manager.removeVirtualLink(virtualLink.networkId(), virtualLink.src(), virtualLink.dst());
+            // attempt to remove the same virtual link again.
+            manager.removeVirtualLink(virtualLink.networkId(), virtualLink.src(), virtualLink.dst());
+        }
+        virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+        assertTrue("The virtual link set should be empty.", virtualLinks.isEmpty());
+
+        // Add/remove the virtual link again.
+        VirtualLink virtualLink = manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+        manager.removeVirtualLink(virtualLink.networkId(), virtualLink.src(), virtualLink.dst());
+        virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+        assertTrue("The virtual link set should be empty.", virtualLinks.isEmpty());
+    }
+
+    /**
+     * Tests adding the same virtual link twice.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testAddSameVirtualLink() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID2);
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork1.id(), src.deviceId(), src.port(),
+                                  new ConnectPoint(srcVirtualDevice.id(), src.port()));
+
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork1.id(), dst.deviceId(), dst.port(),
+                                  new ConnectPoint(dstVirtualDevice.id(), dst.port()));
+
+        manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+    }
+
+    private VirtualPort getPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
+        Set<VirtualPort> virtualPorts = manager.getVirtualPorts(networkId, deviceId);
+        return  virtualPorts.stream().filter(virtualPort -> virtualPort.number().equals(portNumber))
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Tests add, bind and remove of virtual ports.
+     */
+    @Test
+    public void testAddRemoveVirtualPort() {
+        List<VirtualNetworkEvent.Type> expectedEventTypes = new ArrayList<>();
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        expectedEventTypes.add(VirtualNetworkEvent.Type.TENANT_REGISTERED);
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        expectedEventTypes.add(VirtualNetworkEvent.Type.NETWORK_ADDED);
+        VirtualDevice virtualDevice =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_ADDED);
+        ConnectPoint cp = new ConnectPoint(virtualDevice.id(), PortNumber.portNumber(1));
+
+        manager.createVirtualPort(virtualNetwork1.id(),
+                                  virtualDevice.id(), PortNumber.portNumber(1), cp);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_ADDED);
+        manager.createVirtualPort(virtualNetwork1.id(),
+                                  virtualDevice.id(), PortNumber.portNumber(2), cp);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_ADDED);
+
+        Set<VirtualPort> virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), virtualDevice.id());
+        assertNotNull("The virtual port set should not be null", virtualPorts);
+        assertEquals("The virtual port set size did not match.", 2, virtualPorts.size());
+        virtualPorts.forEach(vp -> assertFalse("Initial virtual port state should be disabled", vp.isEnabled()));
+
+        // verify change state of virtual port (disabled -> enabled)
+        manager.updatePortState(virtualNetwork1.id(), virtualDevice.id(), PortNumber.portNumber(1), true);
+        VirtualPort changedPort = getPort(virtualNetwork1.id(), virtualDevice.id(), PortNumber.portNumber(1));
+        assertNotNull("The changed virtual port should not be null", changedPort);
+        assertEquals("Virtual port state should be enabled", true, changedPort.isEnabled());
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_UPDATED);
+
+        // verify change state of virtual port (disabled -> disabled)
+        manager.updatePortState(virtualNetwork1.id(), virtualDevice.id(), PortNumber.portNumber(2), false);
+        changedPort = getPort(virtualNetwork1.id(), virtualDevice.id(), PortNumber.portNumber(2));
+        assertNotNull("The changed virtual port should not be null", changedPort);
+        assertEquals("Virtual port state should be disabled", false, changedPort.isEnabled());
+        // no VIRTUAL_PORT_UPDATED event is expected - the requested state (disabled) is same as previous state.
+
+        for (VirtualPort virtualPort : virtualPorts) {
+            manager.removeVirtualPort(virtualNetwork1.id(),
+                                      (DeviceId) virtualPort.element().id(), virtualPort.number());
+            expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_REMOVED);
+            // attempt to remove the same virtual port again.
+            manager.removeVirtualPort(virtualNetwork1.id(),
+                                      (DeviceId) virtualPort.element().id(), virtualPort.number());
+        }
+        virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), virtualDevice.id());
+        assertTrue("The virtual port set should be empty.", virtualPorts.isEmpty());
+
+        // Add/remove the virtual port again.
+        VirtualPort virtualPort =
+                manager.createVirtualPort(virtualNetwork1.id(), virtualDevice.id(),
+                                                            PortNumber.portNumber(1), cp);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_ADDED);
+
+        ConnectPoint newCp = new ConnectPoint(DID2, PortNumber.portNumber(2));
+        manager.bindVirtualPort(virtualNetwork1.id(), virtualDevice.id(),
+                                PortNumber.portNumber(1), newCp);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_UPDATED);
+
+        manager.removeVirtualPort(virtualNetwork1.id(),
+                                  (DeviceId) virtualPort.element().id(), virtualPort.number());
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_REMOVED);
+        virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), virtualDevice.id());
+        assertTrue("The virtual port set should be empty.", virtualPorts.isEmpty());
+
+        // Validate that the events were all received in the correct order.
+        validateEvents(expectedEventTypes.toArray(
+                new VirtualNetworkEvent.Type[expectedEventTypes.size()]));
+    }
+
+    /**
+     * Tests when a virtual element is removed, all the other elements depending on it are also removed.
+     */
+    @Test
+    public void testRemoveAllElements() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID2);
+        ConnectPoint src = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork1.id(), src.deviceId(), src.port(),
+                new ConnectPoint(PHYDID1, PortNumber.portNumber(1)));
+
+        ConnectPoint dst = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork1.id(), dst.deviceId(), dst.port(),
+                new ConnectPoint(PHYDID2, PortNumber.portNumber(2)));
+
+        manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork1.id(), dst, src);
+
+        ConnectPoint hostCp = new ConnectPoint(DID1, P1);
+        manager.createVirtualPort(virtualNetwork1.id(), hostCp.deviceId(), hostCp.port(),
+                new ConnectPoint(PHYDID1, P1));
+        manager.createVirtualHost(virtualNetwork1.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+
+        //When a virtual port is removed, all virtual links connected to it should also be removed.
+        manager.removeVirtualPort(virtualNetwork1.id(), DID1, PortNumber.portNumber(1));
+        Set<VirtualLink> virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+        assertTrue("The virtual link set should be empty.", virtualLinks.isEmpty());
+
+        //When a virtual port is removed, all virtual hosts located to it should also be removed.
+        manager.removeVirtualPort(virtualNetwork1.id(), DID1, P1);
+        Set<VirtualHost> virtualHosts = manager.getVirtualHosts(virtualNetwork1.id());
+        assertTrue("The virtual host set should be empty.", virtualHosts.isEmpty());
+
+        manager.createVirtualPort(virtualNetwork1.id(), src.deviceId(), src.port(),
+                new ConnectPoint(PHYDID1, PortNumber.portNumber(1)));
+        manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork1.id(), dst, src);
+        manager.createVirtualPort(virtualNetwork1.id(), hostCp.deviceId(), hostCp.port(),
+                new ConnectPoint(PHYDID1, P1));
+        manager.createVirtualHost(virtualNetwork1.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+
+        //When a virtual device is removed, all virtual ports, hosts and links depended on it should also be removed.
+        manager.removeVirtualDevice(virtualNetwork1.id(), DID1);
+        Set<VirtualPort> virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), DID1);
+        assertTrue("The virtual port set of DID1 should be empty", virtualPorts.isEmpty());
+        virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+        assertTrue("The virtual link set should be empty.", virtualLinks.isEmpty());
+        virtualHosts = manager.getVirtualHosts(virtualNetwork1.id());
+        assertTrue("The virtual host set should be empty.", virtualHosts.isEmpty());
+
+        //When a tenantId is removed, all the virtual networks belonging to it should also be removed.
+        manager.unregisterTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        Set<VirtualNetwork> virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
+        assertNotNull("The virtual network set should not be null", virtualNetworks);
+        assertTrue("The virtual network set should be empty.", virtualNetworks.isEmpty());
+    }
+
+    /**
+     * Tests the addTunnelId() method in the store with a null intent.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testAddTunnelIdNullIntent() {
+        manager.store.addTunnelId(null, null);
+    }
+
+    /**
+     * Tests the removeTunnelId() method in the store with a null intent.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testRemoveTunnelIdNullIntent() {
+        manager.store.removeTunnelId(null, null);
+    }
+
+    /**
+     * Tests the addTunnelId, getTunnelIds(), removeTunnelId() methods with the store.
+     */
+    @Test
+    public void testAddTunnelId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        ConnectPoint cp1 = new ConnectPoint(DID1, P1);
+        ConnectPoint cp2 = new ConnectPoint(DID2, P1);
+
+        VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
+                .networkId(virtualNetwork.id())
+                .key(Key.of("Test", APP_ID))
+                .appId(APP_ID)
+                .ingressPoint(cp1)
+                .egressPoint(cp2)
+                .build();
+
+        TunnelId tunnelId = TunnelId.valueOf("virtual tunnel");
+        // Add the intent to tunnelID mapping to the store.
+        manager.store.addTunnelId(virtualIntent, tunnelId);
+        assertEquals("The tunnels size should match.", 1,
+                     manager.store.getTunnelIds(virtualIntent).size());
+
+        // Remove the intent to tunnelID mapping from the store.
+        manager.store.removeTunnelId(virtualIntent, tunnelId);
+        assertTrue("The tunnels should be empty.",
+                   manager.store.getTunnelIds(virtualIntent).isEmpty());
+    }
+
+
+    /**
+     * Method to create the virtual network for {@code tenantIdValue} for further testing.
+     **/
+    private VirtualNetwork setupVirtualNetworkTopology(String tenantIdValue) {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue));
+        VirtualNetwork virtualNetwork =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue));
+
+        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);
+        VirtualDevice virtualDevice5 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID5);
+
+        ConnectPoint cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
+                                  PortNumber.portNumber(1), cp1);
+
+        ConnectPoint cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
+                                  PortNumber.portNumber(2), cp2);
+
+        ConnectPoint cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
+                                  PortNumber.portNumber(3), cp3);
+
+        ConnectPoint cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
+                                  PortNumber.portNumber(4), cp4);
+
+        ConnectPoint 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);
+
+        ConnectPoint cp8 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(8));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
+                                  PortNumber.portNumber(8), cp8);
+
+        ConnectPoint 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);
+
+        topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        topologyProvider = new DefaultVirtualNetworkProvider();
+        try {
+            TestUtils.setField(topologyProvider, "topologyService", topologyService);
+        } catch (TestUtils.TestUtilsException e) {
+            e.printStackTrace();
+        }
+//        topologyProvider.topologyService = topologyService;
+
+        return virtualNetwork;
+    }
+
+    /**
+     * Test the topologyChanged() method.
+     */
+    @Test
+    public void testTopologyChanged() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(tenantIdValue1);
+        VirtualNetworkProviderService providerService =
+                manager.createProviderService(topologyProvider);
+
+        // 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);
+
+        Topology topology = topologyService.currentTopology();
+        providerService.topologyChanged(topologyProvider.getConnectPoints(topology));
+
+        // Validate that all links are still active.
+        manager.getVirtualLinks(virtualNetwork.id()).forEach(virtualLink -> {
+            assertTrue("The virtual link should be active.",
+                       virtualLink.state().equals(Link.State.ACTIVE));
+        });
+
+        virtualNetworkManagerStore.updateLink(link, link.tunnelId(), Link.State.INACTIVE);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.INACTIVE);
+        providerService.topologyChanged(topologyProvider.getConnectPoints(topology));
+
+        // Validate that all links are active again.
+        manager.getVirtualLinks(virtualNetwork.id()).forEach(virtualLink -> {
+            assertTrue("The virtual link should be active.",
+                       virtualLink.state().equals(Link.State.ACTIVE));
+        });
+    }
+
+    /**
+     * Tests that the get() method returns saved service instances.
+     */
+    @Test
+    public void testServiceGetReturnsSavedInstance() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), DeviceService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), LinkService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), TopologyService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), HostService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), PathService.class);
+
+        // extra setup needed for FlowRuleService, PacketService, GroupService, and IntentService
+        VirtualProviderManager virtualProviderManager = new VirtualProviderManager();
+        virtualProviderManager.registerProvider(new DefaultVirtualFlowRuleProvider());
+        virtualProviderManager.registerProvider(new DefaultVirtualPacketProvider());
+        virtualProviderManager.registerProvider(new DefaultVirtualGroupProvider());
+        testDirectory.add(CoreService.class, coreService)
+                .add(VirtualProviderRegistryService.class, virtualProviderManager)
+                .add(EventDeliveryService.class, new TestEventDispatcher())
+                .add(ClusterService.class, new ClusterServiceAdapter())
+                .add(VirtualNetworkFlowRuleStore.class, new SimpleVirtualFlowRuleStore())
+                .add(VirtualNetworkPacketStore.class, new SimpleVirtualPacketStore())
+                .add(VirtualNetworkGroupStore.class, new SimpleVirtualGroupStore())
+                .add(VirtualNetworkIntentStore.class, new SimpleVirtualIntentStore())
+                .add(VirtualNetworkFlowObjectiveStore.class, new SimpleVirtualFlowObjectiveStore());
+
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), FlowRuleService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), FlowObjectiveService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), PacketService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), GroupService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), IntentService.class);
+    }
+
+    /**
+     * Validates that the get() method returns saved service instances.
+     */
+    private <T> void validateServiceGetReturnsSavedInstance(NetworkId networkId,
+                                                            Class<T> serviceClass) {
+        T serviceInstanceFirst = manager.get(networkId, serviceClass);
+        T serviceInstanceSubsequent = manager.get(networkId, serviceClass);
+        assertSame(serviceClass.getSimpleName() +
+                     ": Subsequent get should be same as the first one",
+                     serviceInstanceFirst, serviceInstanceSubsequent);
+    }
+
+    /**
+     * Method to validate that the actual versus expected virtual network events were
+     * received correctly.
+     *
+     * @param types expected virtual network events.
+     */
+    private void validateEvents(Enum... types) {
+        TestTools.assertAfter(100, () -> {
+            int i = 0;
+            assertEquals("wrong events received", types.length, listener.events.size());
+            for (Event event : listener.events) {
+                assertEquals("incorrect event type", types[i], event.type());
+                i++;
+            }
+            listener.events.clear();
+        });
+    }
+
+    /**
+     * Test listener class to receive virtual network events.
+     */
+    private static class TestListener implements VirtualNetworkListener {
+
+        private List<VirtualNetworkEvent> events = Lists.newArrayList();
+
+        @Override
+        public void event(VirtualNetworkEvent event) {
+            events.add(event);
+        }
+
+    }
+
+    /**
+     * 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/VirtualNetworkMastershipManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManagerTest.java
new file mode 100644
index 0000000..a08ab5c
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManagerTest.java
@@ -0,0 +1,312 @@
+/*
+ * 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;
+
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Futures;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.DefaultControllerNode;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkMastershipStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualMastershipStore;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.mastership.MastershipTermService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.onosproject.net.MastershipRole.MASTER;
+import static org.onosproject.net.MastershipRole.STANDBY;
+import static org.onosproject.net.MastershipRole.NONE;
+
+public class VirtualNetworkMastershipManagerTest {
+
+    private static final NodeId NID_LOCAL = new NodeId("local");
+    private static final NodeId NID_OTHER = new NodeId("foo");
+    private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
+
+    private static final TenantId TID = TenantId.tenantId("1");
+
+    private static final DeviceId VDID1 = DeviceId.deviceId("foo:vd1");
+    private static final DeviceId VDID2 = DeviceId.deviceId("foo:vd2");
+    private static final DeviceId VDID3 = DeviceId.deviceId("foo:vd3");
+    private static final DeviceId VDID4 = DeviceId.deviceId("foo:vd4");
+
+    private static final NodeId NID1 = NodeId.nodeId("n1");
+    private static final NodeId NID2 = NodeId.nodeId("n2");
+    private static final NodeId NID3 = NodeId.nodeId("n3");
+    private static final NodeId NID4 = NodeId.nodeId("n4");
+
+    private static final ControllerNode CNODE1 =
+            new DefaultControllerNode(NID1, IpAddress.valueOf("127.0.1.1"));
+    private static final ControllerNode CNODE2 =
+            new DefaultControllerNode(NID2, IpAddress.valueOf("127.0.1.2"));
+    private static final ControllerNode CNODE3 =
+            new DefaultControllerNode(NID3, IpAddress.valueOf("127.0.1.3"));
+    private static final ControllerNode CNODE4 =
+            new DefaultControllerNode(NID4, IpAddress.valueOf("127.0.1.4"));
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+
+    private VirtualNetworkMastershipManager mastershipMgr1;
+    private VirtualNetworkMastershipManager mastershipMgr2;
+    protected MastershipService service;
+    private TestClusterService testClusterService;
+    private EventDeliveryService eventDeliveryService;
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        TestUtils.setField(manager, "coreService", coreService);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+
+        SimpleVirtualMastershipStore store = new SimpleVirtualMastershipStore();
+        TestUtils.setField(store, "coreService", coreService);
+        store.activate();
+
+        testClusterService = new TestClusterService();
+
+        ServiceDirectory testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(ClusterService.class, testClusterService)
+                .add(VirtualNetworkMastershipStore.class, store);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        createVnets();
+
+        mastershipMgr1 = new VirtualNetworkMastershipManager(manager, vnet1.id());
+        mastershipMgr2 = new VirtualNetworkMastershipManager(manager, vnet2.id());
+        service = mastershipMgr1;
+    }
+
+    private void createVnets() {
+        manager.registerTenantId(TID);
+
+        vnet1 = manager.createVirtualNetwork(TID);
+        manager.createVirtualDevice(vnet1.id(), VDID1);
+        manager.createVirtualDevice(vnet1.id(), VDID2);
+
+        vnet2 = manager.createVirtualNetwork(TID);
+        manager.createVirtualDevice(vnet2.id(), VDID3);
+        manager.createVirtualDevice(vnet2.id(), VDID4);
+    }
+
+    @After
+    public void tearDown() {
+        manager.deactivate();
+        virtualNetworkManagerStore.deactivate();
+    }
+
+    @Test
+    public void setRole() {
+        mastershipMgr1.setRole(NID_OTHER, VDID1, MASTER);
+        assertEquals("wrong local role:", NONE, mastershipMgr1.getLocalRole(VDID1));
+        assertEquals("wrong obtained role:", STANDBY, Futures.getUnchecked(mastershipMgr1.requestRoleFor(VDID1)));
+
+        //set to master
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        assertEquals("wrong local role:", MASTER, mastershipMgr1.getLocalRole(VDID1));
+    }
+
+    @Test
+    public void relinquishMastership() {
+        //no backups - should just turn to NONE for device.
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        assertEquals("wrong role:", MASTER, mastershipMgr1.getLocalRole(VDID1));
+        mastershipMgr1.relinquishMastership(VDID1);
+        assertNull("wrong master:", mastershipMgr1.getMasterFor(VDID2));
+        assertEquals("wrong role:", NONE, mastershipMgr1.getLocalRole(VDID1));
+
+        //not master, nothing should happen
+        mastershipMgr1.setRole(NID_LOCAL, VDID2, NONE);
+        mastershipMgr1.relinquishMastership(VDID2);
+        assertNull("wrong role:", mastershipMgr1.getMasterFor(VDID2));
+
+        //provide NID_OTHER as backup and relinquish
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID1));
+        mastershipMgr1.setRole(NID_OTHER, VDID1, STANDBY);
+        mastershipMgr1.relinquishMastership(VDID1);
+        assertEquals("wrong master:", NID_OTHER, mastershipMgr1.getMasterFor(VDID1));
+    }
+
+    @Test
+    public void requestRoleFor() {
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        mastershipMgr1.setRole(NID_OTHER, VDID2, MASTER);
+
+        //local should be master for one but standby for other
+        assertEquals("wrong role:", MASTER, Futures.getUnchecked(mastershipMgr1.requestRoleFor(VDID1)));
+        assertEquals("wrong role:", STANDBY, Futures.getUnchecked(mastershipMgr1.requestRoleFor(VDID2)));
+    }
+
+    @Test
+    public void getMasterFor() {
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        mastershipMgr1.setRole(NID_OTHER, VDID2, MASTER);
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID1));
+        assertEquals("wrong master:", NID_OTHER, mastershipMgr1.getMasterFor(VDID2));
+
+        //have NID_OTHER hand over VDID2 to NID_LOCAL
+        mastershipMgr1.setRole(NID_LOCAL, VDID2, MASTER);
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID2));
+    }
+
+    @Test
+    public void getDevicesOf() {
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        mastershipMgr1.setRole(NID_LOCAL, VDID2, STANDBY);
+        assertEquals("should be one device:", 1, mastershipMgr1.getDevicesOf(NID_LOCAL).size());
+        //hand both devices to NID_LOCAL
+        mastershipMgr1.setRole(NID_LOCAL, VDID2, MASTER);
+        assertEquals("should be two devices:", 2, mastershipMgr1.getDevicesOf(NID_LOCAL).size());
+    }
+
+    @Test
+    public void termService() {
+        MastershipTermService ts = mastershipMgr1;
+
+        //term = 1 for both
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        assertEquals("inconsistent term: ", 1,
+                     ts.getMastershipTerm(VDID1).termNumber());
+
+        //hand devices to NID_LOCAL and back: term = 1 + 2
+        mastershipMgr1.setRole(NID_OTHER, VDID1, MASTER);
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        assertEquals("inconsistent terms: ",
+                     3, ts.getMastershipTerm(VDID1).termNumber());
+    }
+
+    @Test
+    public void balanceWithVnets() {
+
+        testClusterService.put(CNODE1, ControllerNode.State.ACTIVE);
+        testClusterService.put(CNODE2, ControllerNode.State.ACTIVE);
+
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        mastershipMgr1.setRole(NID_LOCAL, VDID2, MASTER);
+        assertEquals("wrong local role:", MASTER, mastershipMgr1.getLocalRole(VDID1));
+        assertEquals("wrong local role:", MASTER, mastershipMgr1.getLocalRole(VDID2));
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID1));
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID2));
+
+        //do balancing according to vnet Id.
+        mastershipMgr1.balanceRoles();
+        assertEquals("wrong master:", NID1, mastershipMgr1.getMasterFor(VDID1));
+        assertEquals("wrong master:", NID1, mastershipMgr1.getMasterFor(VDID2));
+
+        mastershipMgr2.setRole(NID_LOCAL, VDID3, MASTER);
+        mastershipMgr2.setRole(NID_LOCAL, VDID4, MASTER);
+        assertEquals("wrong local role:", MASTER, mastershipMgr2.getLocalRole(VDID3));
+        assertEquals("wrong local role:", MASTER, mastershipMgr2.getLocalRole(VDID4));
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr2.getMasterFor(VDID3));
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr2.getMasterFor(VDID4));
+
+        //do balancing according to vnet Id.
+        mastershipMgr2.balanceRoles();
+        assertEquals("wrong master:", NID2, mastershipMgr2.getMasterFor(VDID3));
+        assertEquals("wrong master:", NID2, mastershipMgr2.getMasterFor(VDID4));
+
+        // make N1 inactive
+        testClusterService.put(CNODE1, ControllerNode.State.INACTIVE);
+        mastershipMgr1.balanceRoles();
+        assertEquals("wrong master:", NID2, mastershipMgr1.getMasterFor(VDID1));
+        assertEquals("wrong master:", NID2, mastershipMgr1.getMasterFor(VDID2));
+    }
+
+    private final class TestClusterService extends ClusterServiceAdapter {
+
+        final Map<NodeId, ControllerNode> nodes = new HashMap<>();
+        final Map<NodeId, ControllerNode.State> nodeStates = new HashMap<>();
+
+        ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
+
+        @Override
+        public ControllerNode getLocalNode() {
+            return local;
+        }
+
+        @Override
+        public Set<ControllerNode> getNodes() {
+            return Sets.newHashSet(nodes.values());
+        }
+
+        @Override
+        public ControllerNode getNode(NodeId nodeId) {
+            return nodes.get(nodeId);
+        }
+
+        @Override
+        public ControllerNode.State getState(NodeId nodeId) {
+            return nodeStates.get(nodeId);
+        }
+
+        public void put(ControllerNode cn, ControllerNode.State state) {
+            nodes.put(cn.id(), cn);
+            nodeStates.put(cn.id(), state);
+        }
+    }
+
+    private final class TestSimpleMastershipStore extends SimpleVirtualMastershipStore
+            implements VirtualNetworkMastershipStore {
+
+        public TestSimpleMastershipStore(ClusterService clusterService) {
+            super.clusterService = clusterService;
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMeterManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMeterManagerTest.java
new file mode 100644
index 0000000..3eb6e88
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMeterManagerTest.java
@@ -0,0 +1,332 @@
+/*
+ * 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;
+
+import com.google.common.collect.Maps;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onosproject.TestApplicationId;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkMeterStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.event.VirtualListenerRegistryManager;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualMeterProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualMeterProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualMeterStore;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.intent.FakeIntentManager;
+import org.onosproject.net.intent.TestableIntentService;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.DefaultBand;
+import org.onosproject.net.meter.DefaultMeter;
+import org.onosproject.net.meter.DefaultMeterFeatures;
+import org.onosproject.net.meter.DefaultMeterRequest;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterFeaturesKey;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.meter.MeterOperation;
+import org.onosproject.net.meter.MeterOperations;
+import org.onosproject.net.meter.MeterRequest;
+import org.onosproject.net.meter.MeterState;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.*;
+
+/**
+ * Virtual Network meter manager tests.
+ */
+public class VirtualNetworkMeterManagerTest extends VirtualNetworkTestUtil {
+    private static final ProviderId PID = new ProviderId("of", "foo");
+    private static final NodeId NID_LOCAL = new NodeId("local");
+    private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private TestableIntentService intentService = new FakeIntentManager();
+    private ServiceDirectory testDirectory;
+    private VirtualProviderManager providerRegistryService;
+
+    private EventDeliveryService eventDeliveryService;
+    VirtualListenerRegistryManager listenerRegistryManager =
+            VirtualListenerRegistryManager.getInstance();
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private SimpleVirtualMeterStore meterStore;
+
+    private VirtualNetworkMeterManager meterManager1;
+    private VirtualNetworkMeterManager meterManager2;
+
+    private TestProvider provider = new TestProvider();
+    private VirtualMeterProviderService providerService1;
+    private VirtualMeterProviderService providerService2;
+
+    private ApplicationId appId;
+
+    private Meter m1;
+    private Meter m2;
+    private MeterRequest.Builder m1Request;
+    private MeterRequest.Builder m2Request;
+
+    private Map<MeterId, Meter> meters = Maps.newHashMap();
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+        CoreService coreService = new TestCoreService();
+        TestStorageService storageService = new TestStorageService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", storageService);
+        virtualNetworkManagerStore.activate();
+
+        meterStore = new SimpleVirtualMeterStore();
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(provider);
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        TestUtils.setField(manager, "coreService", coreService);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+//        eventDeliveryService.addSink(VirtualEvent.class, listenerRegistryManager);
+
+        appId = new TestApplicationId("MeterManagerTest");
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(StorageService.class, storageService)
+                .add(VirtualNetworkMeterStore.class, meterStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        vnet1 = setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = setupVirtualNetworkTopology(manager, TID2);
+
+        meterManager1 = new VirtualNetworkMeterManager(manager, vnet1.id());
+        meterManager2 = new VirtualNetworkMeterManager(manager, vnet2.id());
+
+        providerService1 = (VirtualMeterProviderService)
+                providerRegistryService.getProviderService(vnet1.id(), VirtualMeterProvider.class);
+        providerService2 = (VirtualMeterProviderService)
+                providerRegistryService.getProviderService(vnet2.id(), VirtualMeterProvider.class);
+
+        assertTrue("provider should be registered",
+                   providerRegistryService.getProviders().contains(provider.id()));
+
+        setupMeterTestVariables();
+    }
+
+    @After
+    public void tearDown() {
+        providerRegistryService.unregisterProvider(provider);
+        assertFalse("provider should not be registered",
+                    providerRegistryService.getProviders().contains(provider.id()));
+
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+
+        virtualNetworkManagerStore.deactivate();
+    }
+
+    /** Test for meter submit(). */
+    @Test
+    public void testAddition() {
+        meterManager1.submit(m1Request.add());
+
+        assertTrue("The meter was not added",
+                   meterManager1.getAllMeters().size() == 1);
+        assertThat(meterManager1.getMeter(VDID1, MeterId.meterId(1)), is(m1));
+
+        assertTrue("The meter shouldn't be added for vnet2",
+                   meterManager2.getAllMeters().size() == 0);
+    }
+
+    /** Test for meter remove(). */
+    @Test
+    public void testRemove() {
+        meterManager1.submit(m1Request.add());
+        meterManager1.withdraw(m1Request.remove(), m1.id());
+
+        assertThat(meterManager1.getMeter(VDID1, MeterId.meterId(1)).state(),
+                   is(MeterState.PENDING_REMOVE));
+
+        providerService1.pushMeterMetrics(m1.deviceId(), Collections.emptyList());
+
+        assertTrue("The meter was not removed", meterManager1.getAllMeters().size() == 0);
+        assertTrue("The meter shouldn't be added for vnet2",
+                   meterManager2.getAllMeters().size() == 0);
+    }
+
+    /** Test for meter submit with multiple devices. */
+    @Test
+    public void testMultipleDevice() {
+        meterManager1.submit(m1Request.add());
+        meterManager1.submit(m2Request.add());
+
+        assertTrue("The meters were not added",
+                   meterManager1.getAllMeters().size() == 2);
+        assertTrue("The meter shouldn't be added for vnet2",
+                   meterManager2.getAllMeters().size() == 0);
+
+        assertThat(meterManager1.getMeter(VDID1, MeterId.meterId(1)), is(m1));
+        assertThat(meterManager1.getMeter(VDID2, MeterId.meterId(1)), is(m2));
+    }
+
+    /** Test for meter features inside store. */
+    @Test
+    public void testMeterFeatures() {
+        //Test for virtual network 1
+        assertEquals(meterStore.getMaxMeters(vnet1.id(),
+                                             MeterFeaturesKey.key(VDID1)), 255L);
+        assertEquals(meterStore.getMaxMeters(vnet1.id(),
+                                             MeterFeaturesKey.key(VDID2)), 2);
+        //Test for virtual network 2
+        assertEquals(meterStore.getMaxMeters(vnet2.id(),
+                                             MeterFeaturesKey.key(VDID1)), 100);
+        assertEquals(meterStore.getMaxMeters(vnet2.id(),
+                                             MeterFeaturesKey.key(VDID2)), 10);
+    }
+
+    /** Set variables such as meters and request required for testing. */
+    private void setupMeterTestVariables() {
+        Band band = DefaultBand.builder()
+                .ofType(Band.Type.DROP)
+                .withRate(500)
+                .build();
+
+        m1 = DefaultMeter.builder()
+                .forDevice(VDID1)
+                .fromApp(appId)
+                .withId(MeterId.meterId(1))
+                .withUnit(Meter.Unit.KB_PER_SEC)
+                .withBands(Collections.singletonList(band))
+                .build();
+
+        m2 = DefaultMeter.builder()
+                .forDevice(VDID2)
+                .fromApp(appId)
+                .withId(MeterId.meterId(1))
+                .withUnit(Meter.Unit.KB_PER_SEC)
+                .withBands(Collections.singletonList(band))
+                .build();
+
+        m1Request = DefaultMeterRequest.builder()
+                .forDevice(VDID1)
+                .fromApp(appId)
+                .withUnit(Meter.Unit.KB_PER_SEC)
+                .withBands(Collections.singletonList(band));
+
+        m2Request = DefaultMeterRequest.builder()
+                .forDevice(VDID2)
+                .fromApp(appId)
+                .withUnit(Meter.Unit.KB_PER_SEC)
+                .withBands(Collections.singletonList(band));
+
+        meterStore.storeMeterFeatures(vnet1.id(),
+                                      DefaultMeterFeatures.builder().forDevice(VDID1)
+                                              .withMaxMeters(255L)
+                                              .withBandTypes(new HashSet<>())
+                                              .withUnits(new HashSet<>())
+                                              .hasStats(false)
+                                              .hasBurst(false)
+                                              .withMaxBands((byte) 0)
+                                              .withMaxColors((byte) 0)
+                                              .build());
+        meterStore.storeMeterFeatures(vnet1.id(),
+                                      DefaultMeterFeatures.builder().forDevice(VDID2)
+                                              .withMaxMeters(2)
+                                              .withBandTypes(new HashSet<>())
+                                              .withUnits(new HashSet<>())
+                                              .hasBurst(false)
+                                              .hasStats(false)
+                                              .withMaxBands((byte) 0)
+                                              .withMaxColors((byte) 0)
+                                              .build());
+
+        meterStore.storeMeterFeatures(vnet2.id(),
+                                      DefaultMeterFeatures.builder().forDevice(VDID1)
+                                              .withMaxMeters(100L)
+                                              .withBandTypes(new HashSet<>())
+                                              .withUnits(new HashSet<>())
+                                              .hasStats(false)
+                                              .hasBurst(false)
+                                              .withMaxBands((byte) 0)
+                                              .withMaxColors((byte) 0)
+                                              .build());
+        meterStore.storeMeterFeatures(vnet2.id(),
+                                      DefaultMeterFeatures.builder().forDevice(VDID2)
+                                              .withMaxMeters(10)
+                                              .withBandTypes(new HashSet<>())
+                                              .withUnits(new HashSet<>())
+                                              .hasBurst(false)
+                                              .hasStats(false)
+                                              .withMaxBands((byte) 0)
+                                              .withMaxColors((byte) 0)
+                                              .build());
+    }
+
+    private class TestProvider
+            extends AbstractVirtualProvider
+            implements VirtualMeterProvider {
+
+        protected TestProvider() {
+            super(PID);
+        }
+
+        @Override
+        public void performMeterOperation(NetworkId networkId, DeviceId deviceId,
+                                          MeterOperations meterOps) {
+
+        }
+
+        @Override
+        public void performMeterOperation(NetworkId networkId, DeviceId deviceId,
+                                          MeterOperation meterOp) {
+            meters.put(meterOp.meter().id(), meterOp.meter());
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerTest.java
new file mode 100644
index 0000000..66ccb73
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerTest.java
@@ -0,0 +1,416 @@
+/*
+ * 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;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.TestApplicationId;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ClusterServiceAdapter;
+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.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkPacketStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualPacketProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowRuleStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualPacketStore;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.*;
+import static org.onosproject.net.flowobjective.Objective.Operation.ADD;
+import static org.onosproject.net.flowobjective.Objective.Operation.REMOVE;
+import static org.onosproject.net.packet.PacketPriority.CONTROL;
+import static org.onosproject.net.packet.PacketPriority.REACTIVE;
+
+/**
+ * Junit tests for VirtualNetworkPacketManager using SimpleVirtualPacketStore.
+ */
+public class VirtualNetworkPacketManagerTest extends VirtualNetworkTestUtil {
+
+    private static final int PROCESSOR_PRIORITY = 1;
+
+    protected VirtualNetworkManager manager;
+    protected DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService = new TestCoreService();
+    protected TestServiceDirectory testDirectory;
+    private EventDeliveryService eventDeliveryService;
+    private VirtualProviderManager providerRegistryService;
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private VirtualPacketProvider provider = new TestPacketProvider();
+    protected VirtualNetworkPacketStore packetStore = new SimpleVirtualPacketStore();
+
+    protected VirtualNetworkPacketManager packetManager1;
+    private VirtualNetworkPacketManager packetManager2;
+
+    private ApplicationId appId = new TestApplicationId("VirtualPacketManagerTest");
+
+    private VirtualFlowRuleProvider flowRuleProvider = new TestFlowRuleProvider();
+    private SimpleVirtualFlowRuleStore flowRuleStore;
+    private SimpleVirtualFlowObjectiveStore flowObjectiveStore;
+    protected StorageService storageService = new TestStorageService();
+
+    @Before
+    public void setUp() throws TestUtils.TestUtilsException {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", storageService);
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        flowObjectiveStore = new SimpleVirtualFlowObjectiveStore();
+        TestUtils.setField(flowObjectiveStore, "storageService", storageService);
+        flowObjectiveStore.activate();
+        flowRuleStore = new SimpleVirtualFlowRuleStore();
+        flowRuleStore.activate();
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(provider);
+        providerRegistryService.registerProvider(flowRuleProvider);
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(ClusterService.class, new ClusterServiceAdapter())
+                .add(VirtualNetworkFlowRuleStore.class, flowRuleStore)
+                .add(VirtualNetworkFlowObjectiveStore.class, flowObjectiveStore)
+                .add(VirtualNetworkPacketStore.class, packetStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+
+        manager.activate();
+
+        vnet1 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID2);
+
+        packetManager1 = new VirtualNetworkPacketManager(manager, vnet1.id());
+        packetManager2 = new VirtualNetworkPacketManager(manager, vnet2.id());
+    }
+
+    /**
+     * Tests the correct usage of addProcessor() for a outbound packet.
+     */
+    @Test
+    public void addProcessorTest() {
+        PacketProcessor testProcessor = new TestProcessor();
+        packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
+
+        assertEquals("1 processor expected", 1,
+                    packetManager1.getProcessors().size());
+        assertEquals("0 processor expected", 0,
+                     packetManager2.getProcessors().size());
+
+        assertEquals("not equal packet processor", testProcessor,
+                     packetManager1.getProcessors().get(0).processor());
+        assertEquals("not equal packet processor priority", PROCESSOR_PRIORITY,
+                     packetManager1.getProcessors().get(0).priority());
+    }
+
+    /**
+     * Tests the correct usage of addProcessor() for a outbound packet.
+     */
+    @Test
+    public void removeProcessorTest() {
+        PacketProcessor testProcessor = new TestProcessor();
+        packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
+
+        assertEquals("1 processor expected", 1,
+                     packetManager1.getProcessors().size());
+        assertEquals("0 processor expected", 0,
+                     packetManager2.getProcessors().size());
+
+        packetManager1.removeProcessor(testProcessor);
+
+        assertEquals("0 processor expected", 0,
+                     packetManager1.getProcessors().size());
+        assertEquals("0 processor expected", 0,
+                     packetManager2.getProcessors().size());
+    }
+
+    /**
+     * Tests the correct usage of emit() for a outbound packet.
+     */
+    @Test
+    public void emitTest() {
+        OutboundPacket packet =
+                new DefaultOutboundPacket(VDID1, DefaultTrafficTreatment.emptyTreatment(), ByteBuffer.allocate(5));
+        packetManager1.emit(packet);
+        assertEquals("Packet not emitted correctly", packet, emittedPacket);
+    }
+
+    /**
+     * Tests the addition and removal of packet requests for a device.
+     *
+     * @throws TestUtils.TestUtilsException
+     */
+    @Test
+    public void requestAndCancelPacketsForDeviceTest() throws TestUtils.TestUtilsException {
+        TestFlowObjectiveService testFlowObjectiveService = new TestFlowObjectiveService();
+        TestUtils.setField(packetManager1, "objectiveService", testFlowObjectiveService);
+        TrafficSelector ts = DefaultTrafficSelector.emptySelector();
+        Optional<DeviceId> optionalDeviceId = Optional.of(VDID3);
+
+        // add first request
+        packetManager1.requestPackets(ts, CONTROL, appId, optionalDeviceId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, ADD);
+
+        // add same request as first
+        packetManager1.requestPackets(ts, CONTROL, appId, optionalDeviceId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, ADD);
+
+        // add second request
+        packetManager1.requestPackets(ts, REACTIVE, appId, optionalDeviceId);
+        assertEquals("2 packets expected", 2, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, ADD);
+
+        // cancel second request
+        packetManager1.cancelPackets(ts, REACTIVE, appId, optionalDeviceId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, REMOVE);
+
+        // cancel second request again
+        packetManager1.cancelPackets(ts, REACTIVE, appId, optionalDeviceId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, REMOVE);
+
+        // cancel first request
+        packetManager1.cancelPackets(ts, CONTROL, appId, optionalDeviceId);
+        assertEquals("0 packet expected", 0, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, REMOVE);
+    }
+
+    /**
+     * Tests the addition and removal of packet requests for all devices in a virtual
+     * network.
+     *
+     * @throws TestUtils.TestUtilsException
+     */
+    @Test
+    public void requestAndCancelPacketsForVnetTest() throws TestUtils.TestUtilsException {
+        TestFlowObjectiveService testFlowObjectiveService = new TestFlowObjectiveService();
+        TestUtils.setField(packetManager1, "objectiveService", testFlowObjectiveService);
+        TrafficSelector ts = DefaultTrafficSelector.emptySelector();
+        Set<VirtualDevice> vnet1Devices = manager.getVirtualDevices(vnet1.id());
+
+        // add first request
+        packetManager1.requestPackets(ts, CONTROL, appId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, ADD);
+
+        // add same request as first
+        packetManager1.requestPackets(ts, CONTROL, appId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, ADD);
+
+        // add second request
+        packetManager1.requestPackets(ts, REACTIVE, appId);
+        assertEquals("2 packets expected", 2, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, ADD);
+
+        // cancel second request
+        packetManager1.cancelPackets(ts, REACTIVE, appId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, REMOVE);
+
+        // cancel second request again
+        packetManager1.cancelPackets(ts, REACTIVE, appId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, REMOVE);
+
+        // cancel first request
+        packetManager1.cancelPackets(ts, CONTROL, appId);
+        assertEquals("0 packet expected", 0, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, REMOVE);
+    }
+
+    protected OutboundPacket emittedPacket = null;
+
+    /**
+     * 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();
+                }
+            };
+        }
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return appId;
+        }
+    }
+
+    private class TestPacketProvider extends AbstractVirtualProvider
+            implements VirtualPacketProvider {
+
+        /**
+         * Creates a provider with the supplied identifier.
+         */
+        protected TestPacketProvider() {
+            super(new ProviderId("test-packet",
+                                 "org.onosproject.virtual.test-packet"));
+        }
+
+        @Override
+        public void emit(NetworkId networkId, OutboundPacket packet) {
+            emittedPacket = packet;
+        }
+
+    }
+
+    private class TestProcessor implements PacketProcessor {
+
+        @Override
+        public void process(PacketContext context) {
+
+        }
+    }
+
+    private class TestFlowObjectiveService extends FlowObjectiveServiceAdapter {
+        // track objectives received for each device
+        private final Map<DeviceId, Set<ForwardingObjective>> deviceFwdObjs = new HashMap<>();
+
+        @Override
+        public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
+            deviceFwdObjs.compute(deviceId, (deviceId1, forwardingObjectives) -> {
+                        if (forwardingObjectives == null) {
+                            return Sets.newHashSet(forwardingObjective);
+                        }
+                        forwardingObjectives.add(forwardingObjective);
+                        return forwardingObjectives;
+                    }
+            );
+        }
+
+        private void validateObjectives(Set<VirtualDevice> vdevs, TrafficSelector ts,
+                                    PacketPriority pp, Objective.Operation op) {
+            assertNotNull("set of devices must not be null", vdevs);
+            for (VirtualDevice vdev: vdevs) {
+                assertTrue("Forwarding objective must exist for device " + vdev.id(),
+                           deviceHasObjective(vdev.id(), ts, pp, op));
+            }
+        }
+
+        private void validateObjectiveForDevice(DeviceId deviceId, TrafficSelector ts,
+                                    PacketPriority pp, Objective.Operation op) {
+            assertNotNull("deviceId must not be null", deviceId);
+            assertTrue("Forwarding objective must exist for device " + deviceId,
+                           deviceHasObjective(deviceId, ts, pp, op));
+        }
+
+        private boolean deviceHasObjective(DeviceId deviceId, TrafficSelector ts,
+                                   PacketPriority pp, Objective.Operation op) {
+            Set<ForwardingObjective> fos = deviceFwdObjs.get(deviceId);
+            if (fos != null) {
+                for (ForwardingObjective fo: fos) {
+                    if (fo.selector().equals(ts)
+                            && fo.priority() == pp.priorityValue()
+                            && fo.op().equals(op)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    private class TestFlowRuleProvider extends AbstractVirtualProvider
+            implements VirtualFlowRuleProvider {
+
+        protected TestFlowRuleProvider() {
+            super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
+        }
+
+        @Override
+        public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
+
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerWithDistStoreTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerWithDistStoreTest.java
new file mode 100644
index 0000000..914d709
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerWithDistStoreTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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;
+
+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.ComponentContextAdapter;
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualPacketStore;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
+import org.onosproject.store.cluster.messaging.MessageSubject;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
+
+import static org.junit.Assert.assertNull;
+
+/**
+ * Junit tests for VirtualNetworkPacketManager using DistributedVirtualPacketStore..
+ * This test class extends VirtualNetworkPacketManagerTest - all the tests defined in
+ * VirtualNetworkPacketManagerTest will run using DistributedVirtualPacketStore.
+ */
+public class VirtualNetworkPacketManagerWithDistStoreTest extends VirtualNetworkPacketManagerTest {
+
+    private DistributedVirtualPacketStore distStore;
+    private ClusterService clusterService = new ClusterServiceAdapter();
+
+    @Before
+    public void setUp() throws TestUtils.TestUtilsException {
+        setUpDistPacketStore();
+        super.setUp();
+        TestUtils.setField(packetManager1, "storageService", storageService);
+    }
+
+    private void setUpDistPacketStore() throws TestUtils.TestUtilsException {
+        distStore = new DistributedVirtualPacketStore();
+        TestUtils.setField(distStore, "cfgService", new ComponentConfigAdapter());
+        TestUtils.setField(distStore, "storageService", storageService);
+        TestUtils.setField(distStore, "clusterService", clusterService);
+        TestUtils.setField(distStore, "communicationService", new TestClusterCommunicationService());
+        TestUtils.setField(distStore, "mastershipService", new TestMastershipService());
+
+        distStore.activate(new ComponentContextAdapter());
+        packetStore = distStore; // super.setUp() will cause Distributed store to be used.
+    }
+
+    @After
+    public void tearDown() {
+        distStore.deactivate();
+    }
+
+    @Override
+    @Test
+    @Ignore("Ignore until there is MastershipService support for virtual devices")
+    public void emitTest() {
+        super.emitTest();
+    }
+
+    /**
+     * Tests the correct usage of emit() for a outbound packet - master of packet's
+     * sendThrough is not local node.
+     */
+    @Test
+    @Ignore("Ignore until there is MastershipService support for virtual devices")
+    public void emit2Test() {
+        OutboundPacket packet =
+                new DefaultOutboundPacket(VDID2, DefaultTrafficTreatment.emptyTreatment(), ByteBuffer.allocate(5));
+        packetManager1.emit(packet);
+        assertNull("Packet should not have been emmitted", emittedPacket);
+    }
+
+    private final class TestMastershipService extends MastershipServiceAdapter {
+        @Override
+        public NodeId getMasterFor(DeviceId deviceId) {
+            if (VDID1.equals(deviceId)) {
+                return clusterService.getLocalNode().id();
+            }
+            return new NodeId("abc");
+        }
+    }
+
+    private final class TestClusterCommunicationService extends ClusterCommunicationServiceAdapter {
+        @Override
+        public <M> CompletableFuture<Void> unicast(M message, MessageSubject subject,
+                                                   Function<M, byte[]> encoder, NodeId toNodeId) {
+            return new CompletableFuture<>();
+        }
+    }
+
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManagerTest.java
new file mode 100644
index 0000000..b8db7ea
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManagerTest.java
@@ -0,0 +1,240 @@
+/*
+ * 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 org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.graph.ScalarWeight;
+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.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.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.ElementId;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+import org.onosproject.net.topology.LinkWeigher;
+import org.onosproject.net.topology.LinkWeigherAdapter;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Junit tests for VirtualNetworkPathService.
+ */
+public class VirtualNetworkPathManagerTest extends TestDeviceParams {
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+
+    private TestServiceDirectory testDirectory;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+    }
+
+    /**
+     * Sets up an empty virtual network (no devices, links).
+     *
+     * @return virtual network
+     */
+    private VirtualNetwork setupEmptyVnet() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        return manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+    }
+
+    /**
+     * Creates a virtual network for further testing.
+     *
+     * @return virtual network
+     */
+    private VirtualNetwork setupVnet() {
+        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);
+
+        ConnectPoint cp11 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice1, 1);
+        ConnectPoint cp12 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice1, 2);
+        ConnectPoint cp23 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice2, 3);
+        ConnectPoint cp24 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice2, 4);
+        ConnectPoint cp35 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice3, 5);
+        ConnectPoint cp36 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice3, 6);
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp11, cp23);
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp23, cp11);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp24, cp35);
+        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp35, cp24);
+        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp12, cp36);
+        virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp36, cp12);
+        virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
+
+        return virtualNetwork;
+    }
+
+    /**
+     * Creates a connect point and related virtual port.
+     *
+     * @param vnet virtual network
+     * @param vDev virtual device
+     * @param portNumber port number
+     * @return connect point
+     */
+    private ConnectPoint createConnectPointAndVirtualPort(
+            VirtualNetwork vnet, VirtualDevice vDev, long portNumber) {
+        ConnectPoint cp = new ConnectPoint(vDev.id(), PortNumber.portNumber(portNumber));
+        manager.createVirtualPort(vnet.id(), cp.deviceId(), cp.port(),
+                                  new ConnectPoint(vDev.id(), cp.port()));
+        return cp;
+    }
+
+    /**
+     * Tests getPaths(), getDisjointPaths()
+     * on a non-empty virtual network.
+     */
+    @Test
+    public void testGetPathsOnNonEmptyVnet() {
+        VirtualNetwork vnet = setupVnet();
+        PathService pathService = manager.get(vnet.id(), PathService.class);
+
+        // src and dest are in vnet and are connected by a virtual link
+        Set<Path> paths = pathService.getPaths(DID1, DID3);
+        validatePaths(paths, 1, 1, DID1, DID3, 1.0);
+
+        LinkWeigher linkWeight = new LinkWeigherAdapter(2.0);
+        paths = pathService.getPaths(DID1, DID3, linkWeight);
+        validatePaths(paths, 1, 1, DID1, DID3, 2.0);
+
+        Set<DisjointPath> disjointPaths = pathService.getDisjointPaths(DID1, DID3);
+        validatePaths(disjointPaths, 1, 1, DID1, DID3, 1.0);
+
+        disjointPaths = pathService.getDisjointPaths(DID1, DID3, linkWeight);
+        validatePaths(disjointPaths, 1, 1, DID1, DID3, 2.0);
+
+        // src and dest are in vnet but are not connected
+        paths = pathService.getPaths(DID4, DID3);
+        assertEquals("incorrect path count", 0, paths.size());
+
+        disjointPaths = pathService.getDisjointPaths(DID4, DID3);
+        assertEquals("incorrect path count", 0, disjointPaths.size());
+
+        // src is in vnet, but dest is not in vnet.
+        DeviceId nonExistentDeviceId = DeviceId.deviceId("nonExistentDevice");
+        paths = pathService.getPaths(DID2, nonExistentDeviceId);
+        assertEquals("incorrect path count", 0, paths.size());
+
+        disjointPaths = pathService.getDisjointPaths(DID2, nonExistentDeviceId);
+        assertEquals("incorrect path count", 0, disjointPaths.size());
+    }
+
+    /**
+     * Tests getPaths(), getDisjointPaths()
+     * on an empty virtual network.
+     */
+    @Test
+    public void testGetPathsOnEmptyVnet() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        PathService pathService = manager.get(vnet.id(), PathService.class);
+
+        Set<Path> paths = pathService.getPaths(DID1, DID3);
+        assertEquals("incorrect path count", 0, paths.size());
+
+        Set<DisjointPath> disjointPaths = pathService.getDisjointPaths(DID1, DID3);
+        assertEquals("incorrect path count", 0, disjointPaths.size());
+    }
+
+    /**
+     * Tests getPaths() using a null source device on an empty virtual network.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPathsWithNullSrc() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        PathService pathService = manager.get(vnet.id(), PathService.class);
+        pathService.getPaths(null, DID3);
+    }
+
+    /**
+     * Tests getPaths() using a null destination device on a non-empty virtual network.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPathsWithNullDest() {
+        VirtualNetwork vnet = setupVnet();
+        PathService pathService = manager.get(vnet.id(), PathService.class);
+        pathService.getPaths(DID1, null);
+    }
+
+
+    // Makes sure the set of paths meets basic expectations.
+    private void validatePaths(Set<? extends Path> paths, int count, int length,
+                               ElementId src, ElementId dst, double cost) {
+        assertEquals("incorrect path count", count, paths.size());
+        for (Path path : paths) {
+            assertEquals("incorrect length", length, path.links().size());
+            assertEquals("incorrect source", src, path.src().elementId());
+            assertEquals("incorrect destination", dst, path.dst().elementId());
+            assertEquals("incorrect cost", ScalarWeight.toWeight(cost), path.weight());
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTestUtil.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTestUtil.java
new file mode 100644
index 0000000..d1b7274
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTestUtil.java
@@ -0,0 +1,107 @@
+/*
+ * 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;
+
+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.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+
+import static org.onosproject.net.DeviceId.deviceId;
+
+public class VirtualNetworkTestUtil extends TestDeviceParams {
+
+    protected static final TenantId TID1 = TenantId.tenantId("tid1");
+    protected static final TenantId TID2 = TenantId.tenantId("tid2");
+
+    protected static final DeviceId VDID1 = deviceId("of:foo_v");
+    protected static final DeviceId VDID2 = deviceId("of:bar_v");
+    protected static final DeviceId VDID3 = deviceId("of:who_v");
+    protected static final DeviceId VDID4 = deviceId("of:what_v");
+
+    protected static final DeviceId PHYDID1 = deviceId("physical:1");
+    protected static final DeviceId PHYDID2 = deviceId("physical:2");
+    protected static final DeviceId PHYDID3 = deviceId("physical:3");
+    protected static final DeviceId PHYDID4 = deviceId("physical:4");
+
+    /**
+     * Method to create the virtual network for further testing.
+     *
+     * @return virtual network
+     */
+    public static VirtualNetwork setupVirtualNetworkTopology(VirtualNetworkManager manager,
+                                                             TenantId tenantId) {
+        manager.registerTenantId(tenantId);
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(tenantId);
+
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID2);
+        VirtualDevice virtualDevice3 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID3);
+        VirtualDevice virtualDevice4 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID4);
+
+        ConnectPoint vcp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
+        ConnectPoint cp1 = new ConnectPoint(DID1, PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), vcp1.deviceId(), vcp1.port(), cp1);
+
+        ConnectPoint vcp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
+        ConnectPoint cp2 = new ConnectPoint(DID1, PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), vcp2.deviceId(), vcp2.port(), cp2);
+
+        ConnectPoint vcp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
+        ConnectPoint cp3 = new ConnectPoint(DID2, PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), vcp3.deviceId(), vcp3.port(), cp3);
+
+        ConnectPoint vcp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
+        ConnectPoint cp4 = new ConnectPoint(DID2, PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), vcp4.deviceId(), vcp4.port(), cp4);
+
+        ConnectPoint vcp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
+        ConnectPoint cp5 = new ConnectPoint(DID3, PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), vcp5.deviceId(), vcp5.port(), cp5);
+
+        ConnectPoint vcp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
+        ConnectPoint cp6 = new ConnectPoint(DID3, PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), vcp6.deviceId(), vcp6.port(), cp6);
+
+        DistributedVirtualNetworkStore virtualNetworkManagerStore =
+                (DistributedVirtualNetworkStore) manager.store;
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), vcp1, vcp3);
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), vcp3, vcp1);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), vcp4, vcp5);
+        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), vcp5, vcp4);
+        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), vcp2, vcp6);
+        virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), vcp6, vcp2);
+        virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
+
+        return virtualNetwork;
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManagerTest.java
new file mode 100644
index 0000000..8fb7904
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManagerTest.java
@@ -0,0 +1,642 @@
+/*
+ * 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 org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.graph.ScalarWeight;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+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.DefaultApplicationId;
+import org.onosproject.core.IdGenerator;
+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.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+import org.onosproject.net.topology.LinkWeigher;
+import org.onosproject.net.topology.LinkWeigherAdapter;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyCluster;
+import org.onosproject.net.topology.TopologyService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Junit tests for VirtualNetworkTopologyService.
+ */
+public class VirtualNetworkTopologyManagerTest extends TestDeviceParams {
+
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService;
+    private TestServiceDirectory testDirectory;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+        coreService = new VirtualNetworkTopologyManagerTest.TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, 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);
+
+        ConnectPoint cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), cp1.deviceId(), cp1.port(), cp1);
+
+        ConnectPoint cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), cp2.deviceId(), cp2.port(), cp2);
+
+        ConnectPoint cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
+        manager.createVirtualPort(virtualNetwork.id(), cp3.deviceId(), cp3.port(), cp3);
+
+        ConnectPoint cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
+        manager.createVirtualPort(virtualNetwork.id(), cp4.deviceId(), cp4.port(), cp4);
+
+        ConnectPoint cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
+        manager.createVirtualPort(virtualNetwork.id(), cp5.deviceId(), cp5.port(), cp5);
+
+        ConnectPoint cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
+        manager.createVirtualPort(virtualNetwork.id(), cp6.deviceId(), cp6.port(), cp6);
+
+        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(), cp2, cp6);
+        virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp6, cp2);
+        virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
+
+        return virtualNetwork;
+    }
+
+    /**
+     * Tests the currentTopology() method.
+     */
+    @Test
+    public void testCurrentTopology() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+        assertNotNull("The topology should not be null.", topology);
+    }
+
+    /**
+     * Test isLatest() method using a null topology.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsLatestByNullTopology() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+
+        // test the isLatest() method with a null topology.
+        topologyService.isLatest(null);
+    }
+
+    /**
+     * Test isLatest() method.
+     */
+    @Test
+    public void testIsLatest() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        // test the isLatest() method.
+        assertTrue("This should be latest topology", topologyService.isLatest(topology));
+
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the isLatest() method where a new device has been added to the current topology.
+        assertFalse("This should not be latest topology", topologyService.isLatest(topology));
+
+        topology = topologyService.currentTopology();
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), src.deviceId(), src.port(),
+                                  new ConnectPoint(srcVirtualDevice.id(), src.port()));
+
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), dst.deviceId(), dst.port(),
+                                  new ConnectPoint(dstVirtualDevice.id(), dst.port()));
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), src, dst);
+
+        // test the isLatest() method where a new link has been added to the current topology.
+        assertFalse("This should not be latest topology", topologyService.isLatest(topology));
+    }
+
+    /**
+     * Test getGraph() method.
+     */
+    @Test
+    public void testGetGraph() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        // test the getGraph() method.
+        assertNotNull("The graph should not be null.", topologyService.getGraph(topology));
+    }
+
+    /**
+     * Test getClusters() method.
+     */
+    @Test
+    public void testGetClusters() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+
+        Topology topology = topologyService.currentTopology();
+
+        // test the getClusters() method.
+        assertNotNull("The clusters should not be null.", topologyService.getClusters(topology));
+        assertEquals("The clusters size did not match.", 2, topologyService.getClusters(topology).size());
+    }
+
+    /**
+     * Test getCluster() method using a null cluster identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetClusterUsingNullClusterId() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        Set<TopologyCluster> clusters = topologyService.getClusters(topology);
+        TopologyCluster cluster = clusters.stream().findFirst().get();
+
+        // test the getCluster() method with a null cluster identifier
+        TopologyCluster cluster1 = topologyService.getCluster(topology, null);
+    }
+
+    /**
+     * Test getCluster() method.
+     */
+    @Test
+    public void testGetCluster() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        Set<TopologyCluster> clusters = topologyService.getClusters(topology);
+        assertNotNull("The clusters should not be null.", clusters);
+        assertEquals("The clusters size did not match.", 2, clusters.size());
+
+        // test the getCluster() method.
+        TopologyCluster cluster = clusters.stream().findFirst().get();
+        assertNotNull("The cluster should not be null.", cluster);
+        TopologyCluster cluster1 = topologyService.getCluster(topology, cluster.id());
+        assertNotNull("The cluster should not be null.", cluster1);
+        assertEquals("The cluster ID did not match.", cluster.id(), cluster1.id());
+    }
+
+    /**
+     * Test getClusterDevices() methods with a null cluster.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetClusterDevicesUsingNullCluster() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+        Set<TopologyCluster> clusters = topologyService.getClusters(topology);
+
+        // test the getClusterDevices() method using a null cluster.
+        Object[] objects = clusters.stream().toArray();
+        assertNotNull("The cluster should not be null.", objects);
+        Set<DeviceId> clusterDevices = topologyService.getClusterDevices(topology, null);
+    }
+
+    /**
+     * Test getClusterLinks() methods with a null cluster.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetClusterLinksUsingNullCluster() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+        Set<TopologyCluster> clusters = topologyService.getClusters(topology);
+
+        // test the getClusterLinks() method using a null cluster.
+        Object[] objects = clusters.stream().toArray();
+        assertNotNull("The cluster should not be null.", objects);
+        Set<Link> clusterLinks = topologyService.getClusterLinks(topology, null);
+    }
+
+    /**
+     * Test getClusterDevices() and getClusterLinks() methods.
+     */
+    @Test
+    public void testGetClusterDevicesLinks() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        Set<TopologyCluster> clusters = topologyService.getClusters(topology);
+        assertNotNull("The clusters should not be null.", clusters);
+        assertEquals("The clusters size did not match.", 2, clusters.size());
+
+        // test the getClusterDevices() method.
+        Object[] objects = clusters.stream().toArray();
+        assertNotNull("The cluster should not be null.", objects);
+        Set<DeviceId> clusterDevices = topologyService.getClusterDevices(topology, (TopologyCluster) objects[0]);
+        assertNotNull("The devices should not be null.", clusterDevices);
+        assertEquals("The devices size did not match.", 3, clusterDevices.size());
+        Set<DeviceId> clusterDevices1 = topologyService.getClusterDevices(topology, (TopologyCluster) objects[1]);
+        assertNotNull("The devices should not be null.", clusterDevices1);
+        assertEquals("The devices size did not match.", 1, clusterDevices1.size());
+
+        // test the getClusterLinks() method.
+        Set<Link> clusterLinks = topologyService.getClusterLinks(topology, (TopologyCluster) objects[0]);
+        assertNotNull("The links should not be null.", clusterLinks);
+        assertEquals("The links size did not match.", 6, clusterLinks.size());
+        Set<Link> clusterLinks1 = topologyService.getClusterLinks(topology, (TopologyCluster) objects[1]);
+        assertNotNull("The links should not be null.", clusterLinks1);
+        assertEquals("The links size did not match.", 0, clusterLinks1.size());
+    }
+
+    /**
+     * Test getPaths() method using a null src device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPathsUsingNullSrcDeviceId() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getPaths() method using a null src device identifier.
+        Set<Path> paths = topologyService.getPaths(topology, null, dstVirtualDevice.id());
+    }
+
+    /**
+     * Test getPaths() method using a null dst device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPathsUsingNullDstDeviceId() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getPaths() method using a null dst device identifier.
+        Set<Path> paths = topologyService.getPaths(topology, srcVirtualDevice.id(), null);
+    }
+
+    /**
+     * Test getPaths() method using a null weight.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPathsUsingNullWeight() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getPaths() method using a null weight.
+        Set<Path> paths = topologyService.getPaths(topology, srcVirtualDevice.id(),
+                dstVirtualDevice.id(), (LinkWeigher) null);
+    }
+
+    /**
+     * Test getPaths() and getPaths() by weight methods.
+     */
+    @Test
+    public void testGetPaths() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getPaths() method.
+        Set<Path> paths = topologyService.getPaths(topology, srcVirtualDevice.id(), dstVirtualDevice.id());
+        assertNotNull("The paths should not be null.", paths);
+        assertEquals("The paths size did not match.", 1, paths.size());
+
+        // test the getPaths() by weight method.
+        LinkWeigher weight = new LinkWeigherAdapter(1.0);
+        Set<Path> paths1 = topologyService.getPaths(topology, srcVirtualDevice.id(), dstVirtualDevice.id(), weight);
+        assertNotNull("The paths should not be null.", paths1);
+        assertEquals("The paths size did not match.", 1, paths1.size());
+        Path path = paths1.iterator().next();
+        assertEquals("wrong path length", 1, path.links().size());
+        assertEquals("wrong path cost", ScalarWeight.toWeight(1.0), path.weight());
+    }
+
+    /**
+     * Test getDisjointPaths() methods using a null src device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDisjointPathsUsingNullSrcDeviceId() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getDisjointPaths() method using a null src device identifier.
+        Set<DisjointPath> paths = topologyService.getDisjointPaths(topology, null, dstVirtualDevice.id());
+    }
+
+    /**
+     * Test getDisjointPaths() methods using a null dst device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDisjointPathsUsingNullDstDeviceId() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getDisjointPaths() method using a null dst device identifier.
+        Set<DisjointPath> paths = topologyService.getDisjointPaths(topology, srcVirtualDevice.id(), null);
+    }
+
+    /**
+     * Test getDisjointPaths() methods using a null weight.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDisjointPathsUsingNullWeight() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getDisjointPaths() method using a null weight.
+        Set<DisjointPath> paths = topologyService.getDisjointPaths(topology, srcVirtualDevice.id(),
+                                                                   dstVirtualDevice.id(), (LinkWeigher) null);
+    }
+
+    /**
+     * Test getDisjointPaths() methods using a null risk profile.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDisjointPathsUsingNullRiskProfile() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getDisjointPaths() method using a null risk profile.
+        Set<DisjointPath> paths = topologyService.getDisjointPaths(topology, srcVirtualDevice.id(),
+                                                                   dstVirtualDevice.id(), (Map<Link, Object>) null);
+    }
+
+    /**
+     * Test getDisjointPaths() methods.
+     */
+    @Test
+    public void testGetDisjointPaths() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getDisjointPaths() method.
+        Set<DisjointPath> paths = topologyService.getDisjointPaths(topology, srcVirtualDevice.id(),
+                                                                   dstVirtualDevice.id());
+        assertNotNull("The paths should not be null.", paths);
+        assertEquals("The paths size did not match.", 1, paths.size());
+
+        // test the getDisjointPaths() method using a weight.
+        LinkWeigher weight = new LinkWeigherAdapter(1.0);
+        Set<DisjointPath> paths1 = topologyService.getDisjointPaths(topology, srcVirtualDevice.id(),
+                                                                    dstVirtualDevice.id(), weight);
+        assertNotNull("The paths should not be null.", paths1);
+        assertEquals("The paths size did not match.", 1, paths1.size());
+    }
+
+    /**
+     * Test isInfrastructure() method using a null connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsInfrastructureUsingNullConnectPoint() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        // test the isInfrastructure() method using a null connect point.
+        Boolean isInfrastructure = topologyService.isInfrastructure(topology, null);
+    }
+
+    /**
+     * Test isInfrastructure() method.
+     */
+    @Test
+    public void testIsInfrastructure() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID4);
+        ConnectPoint cp1 = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        ConnectPoint cp2 = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+
+        // test the isInfrastructure() method.
+        Boolean isInfrastructure = topologyService.isInfrastructure(topology, cp1);
+        assertTrue("The connect point should be infrastructure.", isInfrastructure);
+
+        isInfrastructure = topologyService.isInfrastructure(topology, cp2);
+        assertFalse("The connect point should not be infrastructure.", isInfrastructure);
+    }
+
+    /**
+     * Test isBroadcastPoint() method using a null connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsBroadcastUsingNullConnectPoint() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        // test the isInfrastructure() method using a null connect point.
+        Boolean isInfrastructure = topologyService.isBroadcastPoint(topology, null);
+    }
+
+    /**
+     * Test isBroadcastPoint() method.
+     */
+    @Test
+    public void testIsBroadcastPoint() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        ConnectPoint cp = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+
+        // test the isBroadcastPoint() method.
+        Boolean isBroadcastPoint = topologyService.isBroadcastPoint(topology, cp);
+        assertTrue("The connect point should be a broadcast point.", isBroadcastPoint);
+    }
+
+    /**
+     * Return the virtual device matching the device identifier.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId  device identifier
+     * @return virtual device
+     */
+    private VirtualDevice getVirtualDevice(NetworkId networkId, DeviceId deviceId) {
+        Optional<VirtualDevice> foundDevice = manager.getVirtualDevices(networkId)
+                .stream()
+                .filter(device -> deviceId.equals(device.id()))
+                .findFirst();
+        if (foundDevice.isPresent()) {
+            return foundDevice.get();
+        }
+        return null;
+    }
+
+    /**
+     * Core service test class.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+        ApplicationId appId;
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            appId = new DefaultApplicationId(1, name);
+            return appId;
+        }
+
+            @Override
+        public ApplicationId getAppId(String name) {
+            return appId;
+        }
+    }
+
+}
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> {
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/TenantWebResourceTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/TenantWebResourceTest.java
new file mode 100644
index 0000000..def32c5
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/TenantWebResourceTest.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2018-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.rest;
+
+import com.eclipsesource.json.Json;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableSet;
+import org.glassfish.jersey.client.ClientProperties;
+import org.hamcrest.Description;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.rest.resources.ResourceTest;
+
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.HashSet;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * Unit tests for tenant REST APIs.
+ */
+@Ignore
+public class TenantWebResourceTest extends ResourceTest {
+
+    private final VirtualNetworkAdminService mockVnetAdminService = createMock(VirtualNetworkAdminService.class);
+
+    final HashSet<TenantId> tenantIdSet = new HashSet<>();
+
+    private static final String ID = "id";
+
+    private final TenantId tenantId1 = TenantId.tenantId("TenantId1");
+    private final TenantId tenantId2 = TenantId.tenantId("TenantId2");
+    private final TenantId tenantId3 = TenantId.tenantId("TenantId3");
+    private final TenantId tenantId4 = TenantId.tenantId("TenantId4");
+
+    /**
+     * Sets up the global values for all the tests.
+     */
+    @Before
+    public void setUpTest() {
+        // Register the services needed for the test
+        CodecManager codecService = new CodecManager();
+        codecService.activate();
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(VirtualNetworkAdminService.class, mockVnetAdminService)
+                        .add(CodecService.class, codecService);
+
+        setServiceDirectory(testDirectory);
+    }
+
+    /**
+     * Hamcrest matcher to check that a tenant id representation in JSON matches
+     * the actual tenant id.
+     */
+    public static class TenantIdJsonMatcher extends TypeSafeMatcher<JsonObject> {
+        private final TenantId tenantId;
+        private String reason = "";
+
+        public TenantIdJsonMatcher(TenantId tenantIdValue) {
+            tenantId = tenantIdValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonHost) {
+            // Check the tenant id
+            final String jsonId = jsonHost.get(ID).asString();
+            if (!jsonId.equals(tenantId.id())) {
+                reason = ID + " " + tenantId.id();
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a tenant id array matcher.
+     *
+     * @param tenantId tenant id object we are looking for
+     * @return matcher
+     */
+    private static TenantIdJsonMatcher matchesTenantId(TenantId tenantId) {
+        return new TenantIdJsonMatcher(tenantId);
+    }
+
+    /**
+     * Hamcrest matcher to check that a tenant id is represented properly in a JSON
+     * array of tenant ids.
+     */
+    public static class TenantIdJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+        private final TenantId tenantId;
+        private String reason = "";
+
+        public TenantIdJsonArrayMatcher(TenantId tenantIdValue) {
+            tenantId = tenantIdValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            boolean tenantIdFound = false;
+            final int expectedAttributes = 1;
+            for (int tenantIdIndex = 0; tenantIdIndex < json.size();
+                 tenantIdIndex++) {
+
+                final JsonObject jsonHost = json.get(tenantIdIndex).asObject();
+
+                // Only 1 attribute - ID.
+                if (jsonHost.names().size() < expectedAttributes) {
+                    reason = "Found a tenant id with the wrong number of attributes";
+                    return false;
+                }
+
+                final String jsonDeviceKeyId = jsonHost.get(ID).asString();
+                if (jsonDeviceKeyId.equals(tenantId.id())) {
+                    tenantIdFound = true;
+
+                    //  We found the correct tenant id, check the tenant id attribute values
+                    assertThat(jsonHost, matchesTenantId(tenantId));
+                }
+            }
+            if (!tenantIdFound) {
+                reason = "Tenant id " + tenantId.id() + " was not found";
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a tenant id array matcher.
+     *
+     * @param tenantId tenant id object we are looking for
+     * @return matcher
+     */
+    private static TenantIdJsonArrayMatcher hasTenantId(TenantId tenantId) {
+        return new TenantIdJsonArrayMatcher(tenantId);
+    }
+
+    /**
+     * Tests the result of the REST API GET when there are no tenant ids.
+     */
+    @Test
+    public void testGetTenantsEmptyArray() {
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        String response = wt.path("tenants").request().get(String.class);
+        assertThat(response, is("{\"tenants\":[]}"));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when tenant ids are defined.
+     */
+    @Test
+    public void testGetTenantIdsArray() {
+        tenantIdSet.add(tenantId1);
+        tenantIdSet.add(tenantId2);
+        tenantIdSet.add(tenantId3);
+        tenantIdSet.add(tenantId4);
+        expect(mockVnetAdminService.getTenantIds()).andReturn(tenantIdSet).anyTimes();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        String response = wt.path("tenants").request().get(String.class);
+        assertThat(response, containsString("{\"tenants\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("tenants"));
+
+        final JsonArray tenantIds = result.get("tenants").asArray();
+        assertThat(tenantIds, notNullValue());
+        assertEquals("Device keys array is not the correct size.",
+                     tenantIdSet.size(), tenantIds.size());
+
+        tenantIdSet.forEach(tenantId -> assertThat(tenantIds, hasTenantId(tenantId)));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of new tenant id using POST via JSON stream.
+     */
+    @Test
+    public void testPost() {
+        mockVnetAdminService.registerTenantId(anyObject());
+        tenantIdSet.add(tenantId2);
+        expect(mockVnetAdminService.getTenantIds()).andReturn(tenantIdSet).anyTimes();
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = TenantWebResourceTest.class
+                .getResourceAsStream("post-tenant.json");
+
+        Response response = wt.path("tenants").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/tenants/" + tenantId2));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null tenant id using POST via JSON stream.
+     */
+    @Test
+    public void testPostNullTenantId() {
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String response = wt.path("tenants")
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null tenant id did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a tenant id with DELETE request.
+     */
+    @Test
+    public void testDelete() {
+        expect(mockVnetAdminService.getTenantIds())
+                .andReturn(ImmutableSet.of(tenantId2)).anyTimes();
+        mockVnetAdminService.unregisterTenantId(anyObject());
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        Response response = wt.path("tenants/" + tenantId2)
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests that a DELETE of a non-existent tenant id throws an exception.
+     */
+    @Test
+    public void testDeleteNonExistentDeviceKey() {
+        expect(mockVnetAdminService.getTenantIds())
+                .andReturn(ImmutableSet.of())
+                .anyTimes();
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+
+        try {
+            wt.path("tenants/" + "NON_EXISTENT_TENANT_ID")
+                    .request()
+                    .delete(String.class);
+            fail("Delete of a non-existent tenant did not throw an exception");
+        } catch (NotFoundException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebResourceTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebResourceTest.java
new file mode 100644
index 0000000..3b1bd51
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebResourceTest.java
@@ -0,0 +1,1270 @@
+/*
+ * Copyright 2018-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.rest;
+
+import com.eclipsesource.json.Json;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.glassfish.jersey.client.ClientProperties;
+import org.hamcrest.Description;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
+import org.onosproject.incubator.net.virtual.DefaultVirtualHost;
+import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
+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.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+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.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.PortNumber;
+import org.onosproject.rest.resources.HostResourceTest;
+import org.onosproject.rest.resources.LinksResourceTest;
+import org.onosproject.rest.resources.ResourceTest;
+
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.onosproject.net.PortNumber.portNumber;
+
+/**
+ * Unit tests for virtual network REST APIs.
+ */
+@Ignore
+public class VirtualNetworkWebResourceTest extends ResourceTest {
+
+    private final VirtualNetworkAdminService mockVnetAdminService = createMock(VirtualNetworkAdminService.class);
+    private final VirtualNetworkService mockVnetService = createMock(VirtualNetworkService.class);
+    private CodecManager codecService;
+
+    private final HashSet<VirtualDevice> vdevSet = new HashSet<>();
+    private final HashSet<VirtualPort> vportSet = new HashSet<>();
+
+    private static final String ID = "networkId";
+    private static final String TENANT_ID = "tenantId";
+    private static final String DEVICE_ID = "deviceId";
+    private static final String PORT_NUM = "portNum";
+    private static final String PHYS_DEVICE_ID = "physDeviceId";
+    private static final String PHYS_PORT_NUM = "physPortNum";
+
+    private final TenantId tenantId2 = TenantId.tenantId("TenantId2");
+    private final TenantId tenantId3 = TenantId.tenantId("TenantId3");
+    private final TenantId tenantId4 = TenantId.tenantId("TenantId4");
+
+    private final NetworkId networkId1 = NetworkId.networkId(1);
+    private final NetworkId networkId2 = NetworkId.networkId(2);
+    private final NetworkId networkId3 = NetworkId.networkId(3);
+    private final NetworkId networkId4 = NetworkId.networkId(4);
+
+    private final VirtualNetwork vnet1 = new DefaultVirtualNetwork(networkId1, tenantId3);
+    private final VirtualNetwork vnet2 = new DefaultVirtualNetwork(networkId2, tenantId3);
+    private final VirtualNetwork vnet3 = new DefaultVirtualNetwork(networkId3, tenantId3);
+    private final VirtualNetwork vnet4 = new DefaultVirtualNetwork(networkId4, tenantId3);
+
+    private final DeviceId devId1 = DeviceId.deviceId("devid1");
+    private final DeviceId devId2 = DeviceId.deviceId("devid2");
+    private final DeviceId devId22 = DeviceId.deviceId("dev22");
+
+    private final VirtualDevice vdev1 = new DefaultVirtualDevice(networkId3, devId1);
+    private final VirtualDevice vdev2 = new DefaultVirtualDevice(networkId3, devId2);
+
+    private final Device dev1 = NetTestTools.device("dev1");
+    private final Device dev2 = NetTestTools.device("dev2");
+    private final Device dev22 = NetTestTools.device("dev22");
+
+    private final ConnectPoint cp1 = new ConnectPoint(dev1.id(), portNumber(1));
+    private final ConnectPoint cp2 = new ConnectPoint(dev2.id(), portNumber(2));
+
+    private final VirtualPort vport22 = new DefaultVirtualPort(networkId3,
+                                                               dev22, portNumber(22), cp1);
+    private final VirtualPort vport23 = new DefaultVirtualPort(networkId3,
+                                                               dev22, portNumber(23), cp2);
+
+    private final ConnectPoint cp11 = NetTestTools.connectPoint(devId1.toString(), 21);
+    private final ConnectPoint cp21 = NetTestTools.connectPoint(devId2.toString(), 22);
+    private final ConnectPoint cp12 = NetTestTools.connectPoint(devId1.toString(), 2);
+    private final ConnectPoint cp22 = NetTestTools.connectPoint(devId2.toString(), 22);
+
+    private final VirtualLink vlink1 = DefaultVirtualLink.builder()
+            .networkId(networkId3)
+            .src(cp22)
+            .dst(cp11)
+            .build();
+
+    private final VirtualLink vlink2 = DefaultVirtualLink.builder()
+            .networkId(networkId3)
+            .src(cp12)
+            .dst(cp21)
+            .build();
+
+    private final MacAddress mac1 = MacAddress.valueOf("00:11:00:00:00:01");
+    private final MacAddress mac2 = MacAddress.valueOf("00:22:00:00:00:02");
+    private final VlanId vlan1 = VlanId.vlanId((short) 11);
+    private final VlanId vlan2 = VlanId.vlanId((short) 22);
+    private final IpAddress ip1 = IpAddress.valueOf("10.0.0.1");
+    private final IpAddress ip2 = IpAddress.valueOf("10.0.0.2");
+    private final IpAddress ip3 = IpAddress.valueOf("10.0.0.3");
+
+    private final HostId hId1 = HostId.hostId(mac1, vlan1);
+    private final HostId hId2 = HostId.hostId(mac2, vlan2);
+    private final HostLocation loc1 = new HostLocation(devId1, portNumber(100), 123L);
+    private final HostLocation loc2 = new HostLocation(devId2, portNumber(200), 123L);
+    private final Set<IpAddress> ipSet1 = Sets.newHashSet(ip1, ip2);
+    private final Set<IpAddress> ipSet2 = Sets.newHashSet(ip1, ip3);
+    private final VirtualHost vhost1 = new DefaultVirtualHost(networkId1, hId1,
+                                                              mac1, vlan1, loc1, ipSet1);
+    private final VirtualHost vhost2 = new DefaultVirtualHost(networkId2, hId2,
+                                                              mac2, vlan2, loc2, ipSet2);
+
+
+
+
+    /**
+     * Sets up the global values for all the tests.
+     */
+    @Before
+    public void setUpTest() {
+        // Register the services needed for the test
+        codecService = new CodecManager();
+        codecService.activate();
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(VirtualNetworkAdminService.class, mockVnetAdminService)
+                        .add(VirtualNetworkService.class, mockVnetService)
+                        .add(CodecService.class, codecService);
+
+        setServiceDirectory(testDirectory);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual network entity representation in JSON matches
+     * the actual virtual network entity.
+     */
+    private static final class JsonObjectMatcher<T> extends TypeSafeMatcher<JsonObject> {
+        private final T vnetEntity;
+        private List<String> jsonFieldNames;
+        private String reason = "";
+        private BiFunction<T, String, String> getValue; // get vnetEntity's value
+
+        private JsonObjectMatcher(T vnetEntityValue,
+                                  List<String> jsonFieldNames1,
+                                  BiFunction<T, String, String> getValue1) {
+            vnetEntity = vnetEntityValue;
+            jsonFieldNames = jsonFieldNames1;
+            getValue = getValue1;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonHost) {
+            return jsonFieldNames
+                    .stream()
+                    .allMatch(s -> checkField(jsonHost, s, getValue.apply(vnetEntity, s)));
+        }
+
+        private boolean checkField(JsonObject jsonHost, String jsonFieldName,
+                                   String objectValue) {
+            final String jsonValue = jsonHost.get(jsonFieldName).asString();
+            if (!jsonValue.equals(objectValue)) {
+                reason = jsonFieldName + " " + objectValue;
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual network id array matcher.
+     *
+     * @param obj virtual network id object we are looking for
+     * @return matcher
+     */
+    /**
+     * Factory to allocate a virtual network entity matcher.
+     *
+     * @param obj            virtual network object we are looking for
+     * @param jsonFieldNames JSON field names to check against
+     * @param getValue       function to retrieve value from virtual network object
+     * @param <T>            the type of virtual network object
+     * @return matcher
+     */
+    private static <T> JsonObjectMatcher matchesVnetEntity(T obj, List<String> jsonFieldNames,
+                                                           BiFunction<T, String, String> getValue) {
+        return new JsonObjectMatcher<T>(obj, jsonFieldNames, getValue);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual network entity is represented properly in a JSON
+     * array of virtual network entities.
+     */
+    protected static class JsonArrayMatcher<T> extends TypeSafeMatcher<JsonArray> {
+        private final T vnetEntity;
+        private String reason = "";
+        private Function<T, String> getKey; // gets vnetEntity's key
+        private BiPredicate<T, JsonObject> checkKey; // check vnetEntity's key with JSON rep'n
+        private List<String> jsonFieldNames; // field/property names
+        private BiFunction<T, String, String> getValue; // get vnetEntity's value
+
+        protected JsonArrayMatcher(T vnetEntityValue, Function<T, String> getKey1,
+                                   BiPredicate<T, JsonObject> checkKey1,
+                                   List<String> jsonFieldNames1,
+                                   BiFunction<T, String, String> getValue1) {
+            vnetEntity = vnetEntityValue;
+            getKey = getKey1;
+            checkKey = checkKey1;
+            jsonFieldNames = jsonFieldNames1;
+            getValue = getValue1;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            boolean itemFound = false;
+            final int expectedAttributes = jsonFieldNames.size();
+            for (int jsonArrayIndex = 0; jsonArrayIndex < json.size();
+                 jsonArrayIndex++) {
+
+                final JsonObject jsonHost = json.get(jsonArrayIndex).asObject();
+
+                if (jsonHost.names().size() < expectedAttributes) {
+                    reason = "Found a virtual network with the wrong number of attributes";
+                    return false;
+                }
+
+                if (checkKey != null && checkKey.test(vnetEntity, jsonHost)) {
+                    itemFound = true;
+                    assertThat(jsonHost, matchesVnetEntity(vnetEntity, jsonFieldNames, getValue));
+                }
+            }
+            if (!itemFound) {
+                reason = getKey.apply(vnetEntity) + " was not found";
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Array matcher for VirtualNetwork.
+     */
+    private static final class VnetJsonArrayMatcher extends JsonArrayMatcher<VirtualNetwork> {
+
+        private VnetJsonArrayMatcher(VirtualNetwork vnetIn) {
+            super(vnetIn,
+                  vnet -> "Virtual network " + vnet.id().toString(),
+                  (vnet, jsonObject) -> jsonObject.get(ID).asString().equals(vnet.id().toString()),
+                  ImmutableList.of(ID, TENANT_ID),
+                  (vnet, s) -> s.equals(ID) ? vnet.id().toString()
+                          : s.equals(TENANT_ID) ? vnet.tenantId().toString()
+                          : null
+            );
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual network array matcher.
+     *
+     * @param vnet virtual network object we are looking for
+     * @return matcher
+     */
+    private VnetJsonArrayMatcher hasVnet(VirtualNetwork vnet) {
+        return new VnetJsonArrayMatcher(vnet);
+    }
+
+    // Tests for Virtual Networks
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual networks.
+     */
+    @Test
+    public void testGetVirtualNetworksEmptyArray() {
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetAdminService);
+        expect(mockVnetService.getVirtualNetworks(tenantId4)).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String response = wt.path("vnets").request().get(String.class);
+        assertThat(response, is("{\"vnets\":[]}"));
+
+        verify(mockVnetService);
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual networks are defined.
+     */
+    @Test
+    public void testGetVirtualNetworksArray() {
+        final Set<VirtualNetwork> vnetSet = ImmutableSet.of(vnet1, vnet2, vnet3, vnet4);
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes();
+        replay(mockVnetAdminService);
+        expect(mockVnetService.getVirtualNetworks(tenantId3)).andReturn(vnetSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String response = wt.path("vnets").request().get(String.class);
+        assertThat(response, containsString("{\"vnets\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("vnets"));
+
+        final JsonArray vnetJsonArray = result.get("vnets").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual networks array is not the correct size.",
+                     vnetSet.size(), vnetJsonArray.size());
+
+        vnetSet.forEach(vnet -> assertThat(vnetJsonArray, hasVnet(vnet)));
+
+        verify(mockVnetService);
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests the result of the REST API GET for virtual networks with tenant id.
+     */
+    @Test
+    public void testGetVirtualNetworksByTenantId() {
+        final Set<VirtualNetwork> vnetSet = ImmutableSet.of(vnet1, vnet2, vnet3, vnet4);
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes();
+        replay(mockVnetAdminService);
+        expect(mockVnetService.getVirtualNetworks(tenantId3)).andReturn(vnetSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String response = wt.path("vnets/" + tenantId3.id()).request().get(String.class);
+        assertThat(response, containsString("{\"vnets\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("vnets"));
+
+        final JsonArray vnetJsonArray = result.get("vnets").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual networks array is not the correct size.",
+                     vnetSet.size(), vnetJsonArray.size());
+
+        vnetSet.forEach(vnet -> assertThat(vnetJsonArray, hasVnet(vnet)));
+
+        verify(mockVnetService);
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests the result of the REST API GET for virtual networks with tenant id.
+     */
+    @Test
+    public void testGetVirtualNetworksByNonExistentTenantId() {
+        String tenantIdName = "NON_EXISTENT_TENANT_ID";
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes();
+        replay(mockVnetAdminService);
+        expect(mockVnetService.getVirtualNetworks(anyObject())).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+
+        try {
+            wt.path("vnets/" + tenantIdName)
+                    .request()
+                    .get(String.class);
+            fail("Get of a non-existent virtual network did not throw an exception");
+        } catch (NotFoundException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
+        }
+
+        verify(mockVnetService);
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of new virtual network using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualNetwork() {
+        expect(mockVnetAdminService.createVirtualNetwork(tenantId2)).andReturn(vnet1);
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = TenantWebResourceTest.class
+                .getResourceAsStream("post-tenant.json");
+
+        Response response = wt.path("vnets").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/vnets/" + vnet1.id().toString()));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual network using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualNetworkNullTenantId() {
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            wt.path("vnets")
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual network did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual network with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualNetwork() {
+        mockVnetAdminService.removeVirtualNetwork(anyObject());
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        Response response = wt.path("vnets/" + "2")
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests that a DELETE of a non-existent virtual network throws an exception.
+     */
+    @Test
+    public void testDeleteNetworkNonExistentNetworkId() {
+        expect(mockVnetAdminService.getTenantIds())
+                .andReturn(ImmutableSet.of())
+                .anyTimes();
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+
+        try {
+            wt.path("vnets/" + "NON_EXISTENT_NETWORK_ID")
+                    .request()
+                    .delete(String.class);
+            fail("Delete of a non-existent virtual network did not throw an exception");
+        } catch (NotFoundException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    // Tests for Virtual Device
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual devices.
+     */
+    @Test
+    public void testGetVirtualDevicesEmptyArray() {
+        NetworkId networkId = networkId4;
+        expect(mockVnetService.getVirtualDevices(networkId)).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/devices";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, is("{\"devices\":[]}"));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual devices are defined.
+     */
+    @Test
+    public void testGetVirtualDevicesArray() {
+        NetworkId networkId = networkId3;
+        vdevSet.add(vdev1);
+        vdevSet.add(vdev2);
+        expect(mockVnetService.getVirtualDevices(networkId)).andReturn(vdevSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/devices";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, containsString("{\"devices\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("devices"));
+
+        final JsonArray vnetJsonArray = result.get("devices").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual devices array is not the correct size.",
+                     vdevSet.size(), vnetJsonArray.size());
+
+        vdevSet.forEach(vdev -> assertThat(vnetJsonArray, hasVdev(vdev)));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Array matcher for VirtualDevice.
+     */
+    private static final class VdevJsonArrayMatcher extends JsonArrayMatcher<VirtualDevice> {
+
+        private VdevJsonArrayMatcher(VirtualDevice vdevIn) {
+            super(vdevIn,
+                  vdev -> "Virtual device " + vdev.networkId().toString()
+                          + " " + vdev.id().toString(),
+                  (vdev, jsonObject) -> jsonObject.get(ID).asString().equals(vdev.networkId().toString())
+                          && jsonObject.get(DEVICE_ID).asString().equals(vdev.id().toString()),
+                  ImmutableList.of(ID, DEVICE_ID),
+                  (vdev, s) -> s.equals(ID) ? vdev.networkId().toString()
+                          : s.equals(DEVICE_ID) ? vdev.id().toString()
+                          : null
+            );
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual device array matcher.
+     *
+     * @param vdev virtual device object we are looking for
+     * @return matcher
+     */
+    private VdevJsonArrayMatcher hasVdev(VirtualDevice vdev) {
+        return new VdevJsonArrayMatcher(vdev);
+    }
+    /**
+     * Tests adding of new virtual device using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualDevice() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        expect(mockVnetAdminService.createVirtualDevice(networkId, deviceId)).andReturn(vdev2);
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-device.json");
+        String reqLocation = "vnets/" + networkId.toString() + "/devices";
+        Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/" + reqLocation + "/" + vdev2.id().toString()));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual device using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualDeviceNullJsonStream() {
+        NetworkId networkId = networkId3;
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String reqLocation = "vnets/" + networkId.toString() + "/devices";
+            wt.path(reqLocation)
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual device did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual device with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualDevice() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        mockVnetAdminService.removeVirtualDevice(networkId, deviceId);
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        String reqLocation = "vnets/" + networkId.toString() + "/devices/" + deviceId.toString();
+        Response response = wt.path(reqLocation)
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+
+        verify(mockVnetAdminService);
+    }
+
+    // Tests for Virtual Ports
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual ports.
+     */
+    @Test
+    public void testGetVirtualPortsEmptyArray() {
+        NetworkId networkId = networkId4;
+        DeviceId deviceId = devId2;
+        expect(mockVnetService.getVirtualPorts(networkId, deviceId))
+                .andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString()
+                + "/devices/" + deviceId.toString() + "/ports";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, is("{\"ports\":[]}"));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual ports are defined.
+     */
+    @Test
+    public void testGetVirtualPortsArray() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = dev22.id();
+        vportSet.add(vport23);
+        vportSet.add(vport22);
+        expect(mockVnetService.getVirtualPorts(networkId, deviceId)).andReturn(vportSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString()
+                + "/devices/" + deviceId.toString() + "/ports";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, containsString("{\"ports\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("ports"));
+
+        final JsonArray vnetJsonArray = result.get("ports").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual ports array is not the correct size.",
+                     vportSet.size(), vnetJsonArray.size());
+
+        vportSet.forEach(vport -> assertThat(vnetJsonArray, hasVport(vport)));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Array matcher for VirtualPort.
+     */
+    private static final class VportJsonArrayMatcher extends JsonArrayMatcher<VirtualPort> {
+
+        private VportJsonArrayMatcher(VirtualPort vportIn) {
+            super(vportIn,
+                  vport -> "Virtual port " + vport.networkId().toString() + " "
+                    + vport.element().id().toString() + " " + vport.number().toString(),
+                  (vport, jsonObject) -> jsonObject.get(ID).asString().equals(vport.networkId().toString())
+                          && jsonObject.get(PORT_NUM).asString().equals(vport.number().toString())
+                          && jsonObject.get(DEVICE_ID).asString().equals(vport.element().id().toString()),
+                  ImmutableList.of(ID, DEVICE_ID, PORT_NUM, PHYS_DEVICE_ID, PHYS_PORT_NUM),
+                  (vport, s) -> s.equals(ID) ? vport.networkId().toString()
+                          : s.equals(DEVICE_ID) ? vport.element().id().toString()
+                          : s.equals(PORT_NUM) ? vport.number().toString()
+                          : s.equals(PHYS_DEVICE_ID) ? vport.realizedBy().deviceId().toString()
+                          : s.equals(PHYS_PORT_NUM) ? vport.realizedBy().port().toString()
+                          : null
+            );
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual port array matcher.
+     *
+     * @param vport virtual port object we are looking for
+     * @return matcher
+     */
+    private VportJsonArrayMatcher hasVport(VirtualPort vport) {
+        return new VportJsonArrayMatcher(vport);
+    }
+
+    /**
+     * Tests adding of new virtual port using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualPort() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId22;
+        DefaultAnnotations annotations = DefaultAnnotations.builder().build();
+        Device physDevice = new DefaultDevice(null, DeviceId.deviceId("dev1"),
+                                              null, null, null, null, null, null, annotations);
+        ConnectPoint cp1 = new ConnectPoint(physDevice.id(), portNumber(1));
+        expect(mockVnetAdminService.createVirtualPort(networkId, deviceId, portNumber(22), cp1))
+                .andReturn(vport22);
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-port.json");
+        String reqLocation = "vnets/" + networkId.toString()
+                + "/devices/" + deviceId.toString() + "/ports";
+        Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual port using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualPortNullJsonStream() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String reqLocation = "vnets/" + networkId.toString()
+                    + "/devices/" + deviceId.toString() + "/ports";
+            wt.path(reqLocation)
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual port did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual port with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualPort() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        PortNumber portNum = portNumber(2);
+        mockVnetAdminService.removeVirtualPort(networkId, deviceId, portNum);
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        String reqLocation = "vnets/" + networkId.toString()
+                + "/devices/" + deviceId.toString() + "/ports/" + portNum.toLong();
+        Response response = wt.path(reqLocation)
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+
+        verify(mockVnetAdminService);
+    }
+
+    // Tests for Virtual Links
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual links.
+     */
+    @Test
+    public void testGetVirtualLinksEmptyArray() {
+        NetworkId networkId = networkId4;
+        expect(mockVnetService.getVirtualLinks(networkId)).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/links";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, is("{\"links\":[]}"));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual links are defined.
+     */
+    @Test
+    public void testGetVirtualLinksArray() {
+        NetworkId networkId = networkId3;
+        final Set<VirtualLink> vlinkSet = ImmutableSet.of(vlink1, vlink2);
+        expect(mockVnetService.getVirtualLinks(networkId)).andReturn(vlinkSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/links";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, containsString("{\"links\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("links"));
+
+        final JsonArray vnetJsonArray = result.get("links").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual links array is not the correct size.",
+                     vlinkSet.size(), vnetJsonArray.size());
+
+        vlinkSet.forEach(vlink -> assertThat(vnetJsonArray, hasVlink(vlink)));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual link representation in JSON matches
+     * the actual virtual link.
+     */
+    private static final class VirtualLinkJsonMatcher extends LinksResourceTest.LinkJsonMatcher {
+        private final VirtualLink vlink;
+        private String reason = "";
+
+        private VirtualLinkJsonMatcher(VirtualLink vlinkValue) {
+            super(vlinkValue);
+            vlink = vlinkValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonLink) {
+            if (!super.matchesSafely(jsonLink)) {
+                return false;
+            }
+            // check NetworkId
+            String jsonNetworkId = jsonLink.get(ID).asString();
+            String networkId = vlink.networkId().toString();
+            if (!jsonNetworkId.equals(networkId)) {
+                reason = ID + " was " + jsonNetworkId;
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual link matcher.
+     *
+     * @param vlink virtual link object we are looking for
+     * @return matcher
+     */
+    private static VirtualLinkJsonMatcher matchesVirtualLink(VirtualLink vlink) {
+        return new VirtualLinkJsonMatcher(vlink);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual link is represented properly in a JSON
+     * array of links.
+     */
+    private static final class VirtualLinkJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+        private final VirtualLink vlink;
+        private String reason = "";
+
+        private VirtualLinkJsonArrayMatcher(VirtualLink vlinkValue) {
+            vlink = vlinkValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            for (int jsonLinkIndex = 0; jsonLinkIndex < json.size();
+                 jsonLinkIndex++) {
+
+                JsonObject jsonLink = json.get(jsonLinkIndex).asObject();
+
+                if (matchesVirtualLink(vlink).matchesSafely(jsonLink)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual link array matcher.
+     *
+     * @param vlink virtual link object we are looking for
+     * @return matcher
+     */
+    private VirtualLinkJsonArrayMatcher hasVlink(VirtualLink vlink) {
+        return new VirtualLinkJsonArrayMatcher(vlink);
+    }
+
+    /**
+     * Tests adding of new virtual link using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualLink() {
+        NetworkId networkId = networkId3;
+        expect(mockVnetAdminService.createVirtualLink(networkId, cp22, cp11))
+                .andReturn(vlink1);
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-link.json");
+        String reqLocation = "vnets/" + networkId.toString() + "/links";
+        Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/" + reqLocation));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual link using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualLinkNullJsonStream() {
+        NetworkId networkId = networkId3;
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String reqLocation = "vnets/" + networkId.toString() + "/links";
+            wt.path(reqLocation)
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual link did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual link with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualLink() {
+        NetworkId networkId = networkId3;
+        mockVnetAdminService.removeVirtualLink(networkId, cp22, cp11);
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-link.json");
+        String reqLocation = "vnets/" + networkId.toString() + "/links";
+        Response response = wt.path(reqLocation).request().method("DELETE", Entity.json(jsonStream));
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+        verify(mockVnetAdminService);
+    }
+
+    // Tests for Virtual Hosts
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual hosts.
+     */
+    @Test
+    public void testGetVirtualHostsEmptyArray() {
+        NetworkId networkId = networkId4;
+        expect(mockVnetService.getVirtualHosts(networkId)).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/hosts";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, is("{\"hosts\":[]}"));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual hosts are defined.
+     */
+    @Test
+    public void testGetVirtualHostsArray() {
+        NetworkId networkId = networkId3;
+        final Set<VirtualHost> vhostSet = ImmutableSet.of(vhost1, vhost2);
+        expect(mockVnetService.getVirtualHosts(networkId)).andReturn(vhostSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/hosts";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, containsString("{\"hosts\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("hosts"));
+
+        final JsonArray vnetJsonArray = result.get("hosts").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual hosts array is not the correct size.",
+                     vhostSet.size(), vnetJsonArray.size());
+
+        vhostSet.forEach(vhost -> assertThat(vnetJsonArray, hasVhost(vhost)));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual host representation in JSON matches
+     * the actual virtual host.
+     */
+    private static final class VirtualHostJsonMatcher extends HostResourceTest.HostJsonMatcher {
+        private final VirtualHost vhost;
+        private String reason = "";
+
+        private VirtualHostJsonMatcher(VirtualHost vhostValue) {
+            super(vhostValue);
+            vhost = vhostValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonHost) {
+            if (!super.matchesSafely(jsonHost)) {
+                return false;
+            }
+            // check NetworkId
+            String jsonNetworkId = jsonHost.get(ID).asString();
+            String networkId = vhost.networkId().toString();
+            if (!jsonNetworkId.equals(networkId)) {
+                reason = ID + " was " + jsonNetworkId;
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual host matcher.
+     *
+     * @param vhost virtual host object we are looking for
+     * @return matcher
+     */
+    private static VirtualHostJsonMatcher matchesVirtualHost(VirtualHost vhost) {
+        return new VirtualHostJsonMatcher(vhost);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual host is represented properly in a JSON
+     * array of hosts.
+     */
+    private static final class VirtualHostJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+        private final VirtualHost vhost;
+        private String reason = "";
+
+        private VirtualHostJsonArrayMatcher(VirtualHost vhostValue) {
+            vhost = vhostValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            for (int jsonHostIndex = 0; jsonHostIndex < json.size();
+                 jsonHostIndex++) {
+
+                JsonObject jsonHost = json.get(jsonHostIndex).asObject();
+
+                if (matchesVirtualHost(vhost).matchesSafely(jsonHost)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual host array matcher.
+     *
+     * @param vhost virtual host object we are looking for
+     * @return matcher
+     */
+    private VirtualHostJsonArrayMatcher hasVhost(VirtualHost vhost) {
+        return new VirtualHostJsonArrayMatcher(vhost);
+    }
+
+    /**
+     * Tests adding of new virtual host using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualHost() {
+        NetworkId networkId = networkId3;
+        expect(mockVnetAdminService.createVirtualHost(networkId, hId1, mac1, vlan1, loc1, ipSet1))
+                .andReturn(vhost1);
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-host.json");
+        String reqLocation = "vnets/" + networkId.toString() + "/hosts";
+        Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/" + reqLocation));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual host using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualHostNullJsonStream() {
+        NetworkId networkId = networkId3;
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String reqLocation = "vnets/" + networkId.toString() + "/hosts";
+            wt.path(reqLocation)
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual host did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual host with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualHost() {
+        NetworkId networkId = networkId3;
+        mockVnetAdminService.removeVirtualHost(networkId, hId1);
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-host.json");
+        String reqLocation = "vnets/" + networkId.toString() + "/hosts";
+        Response response = wt.path(reqLocation).request().method("DELETE", Entity.json(jsonStream));
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+        verify(mockVnetAdminService);
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMastershipStoreTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMastershipStoreTest.java
new file mode 100644
index 0000000..58d3506
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMastershipStoreTest.java
@@ -0,0 +1,207 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Futures;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipTerm;
+import org.onosproject.net.DeviceId;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.mastership.MastershipEvent.Type.MASTER_CHANGED;
+import static org.onosproject.net.MastershipRole.MASTER;
+import static org.onosproject.net.MastershipRole.NONE;
+import static org.onosproject.net.MastershipRole.STANDBY;
+
+public class SimpleVirtualMastershipStoreTest {
+
+    private static final NetworkId VNID1 = NetworkId.networkId(1);
+
+    private static final DeviceId VDID1 = DeviceId.deviceId("of:01");
+    private static final DeviceId VDID2 = DeviceId.deviceId("of:02");
+    private static final DeviceId VDID3 = DeviceId.deviceId("of:03");
+    private static final DeviceId VDID4 = DeviceId.deviceId("of:04");
+
+    private static final NodeId N1 = new NodeId("local");
+    private static final NodeId N2 = new NodeId("other");
+
+    private SimpleVirtualMastershipStore sms;
+
+    @Before
+    public void setUp() throws Exception {
+        sms = new SimpleVirtualMastershipStore();
+        sms.activate();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        sms.deactivate();
+    }
+
+    @Test
+    public void getRole() {
+        //special case, no backup or master
+        put(VNID1, VDID1, N1, false, false);
+        assertEquals("wrong role", NONE, sms.getRole(VNID1, N1, VDID1));
+
+        //backup exists but we aren't mapped
+        put(VNID1, VDID2, N1, false, true);
+        assertEquals("wrong role", STANDBY, sms.getRole(VNID1, N1, VDID2));
+
+        //N2 is master
+        put(VNID1, VDID3, N2, true, true);
+        assertEquals("wrong role", MASTER, sms.getRole(VNID1, N2, VDID3));
+
+        //N2 is master but N1 is only in backups set
+        put(VNID1, VDID4, N1, false, true);
+        put(VNID1, VDID4, N2, true, false);
+        assertEquals("wrong role", STANDBY, sms.getRole(VNID1, N1, VDID4));
+    }
+
+    @Test
+    public void getMaster() {
+        put(VNID1, VDID3, N2, true, true);
+        assertEquals("wrong role", MASTER, sms.getRole(VNID1, N2, VDID3));
+        assertEquals("wrong node", N2, sms.getMaster(VNID1, VDID3));
+    }
+
+    @Test
+    public void setMaster() {
+        put(VNID1, VDID1, N1, false, false);
+        assertEquals("wrong event", MASTER_CHANGED,
+                     Futures.getUnchecked(sms.setMaster(VNID1, N1, VDID1)).type());
+        assertEquals("wrong role", MASTER, sms.getRole(VNID1, N1, VDID1));
+        //set node that's already master - should be ignored
+        assertNull("wrong event",
+                   Futures.getUnchecked(sms.setMaster(VNID1, N1, VDID1)));
+
+        //set STANDBY to MASTER
+        put(VNID1, VDID2, N1, false, true);
+        assertEquals("wrong role", STANDBY, sms.getRole(VNID1, N1, VDID2));
+        assertEquals("wrong event", MASTER_CHANGED,
+                     Futures.getUnchecked(sms.setMaster(VNID1, N1, VDID2)).type());
+        assertEquals("wrong role", MASTER, sms.getRole(VNID1, N1, VDID2));
+    }
+
+    @Test
+    public void getDevices() {
+        Set<DeviceId> d = Sets.newHashSet(VDID1, VDID2);
+
+        put(VNID1, VDID1, N2, true, true);
+        put(VNID1, VDID2, N2, true, true);
+        put(VNID1, VDID3, N1, true, true);
+        assertTrue("wrong devices", d.equals(sms.getDevices(VNID1, N2)));
+    }
+
+    @Test
+    public void getTermFor() {
+        put(VNID1, VDID1, N1, true, true);
+        assertEquals("wrong term", MastershipTerm.of(N1, 0),
+                     sms.getTermFor(VNID1, VDID1));
+
+        //switch to N2 and back - 2 term switches
+        sms.setMaster(VNID1, N2, VDID1);
+        sms.setMaster(VNID1, N1, VDID1);
+        assertEquals("wrong term", MastershipTerm.of(N1, 2),
+                     sms.getTermFor(VNID1, VDID1));
+    }
+
+    @Test
+    public void requestRole() {
+        //NONE - become MASTER
+        put(VNID1, VDID1, N1, false, false);
+        assertEquals("wrong role", MASTER,
+                     Futures.getUnchecked(sms.requestRole(VNID1, VDID1)));
+
+        //was STANDBY - become MASTER
+        put(VNID1, VDID2, N1, false, true);
+        assertEquals("wrong role", MASTER,
+                     Futures.getUnchecked(sms.requestRole(VNID1, VDID2)));
+
+        //other MASTER - stay STANDBY
+        put(VNID1, VDID3, N2, true, false);
+        assertEquals("wrong role", STANDBY,
+                     Futures.getUnchecked(sms.requestRole(VNID1, VDID3)));
+
+        //local (N1) is MASTER - stay MASTER
+        put(VNID1, VDID4, N1, true, true);
+        assertEquals("wrong role", MASTER,
+                     Futures.getUnchecked(sms.requestRole(VNID1, VDID4)));
+    }
+
+    @Test
+    public void unsetMaster() {
+        //NONE - record backup but take no other action
+        put(VNID1, VDID1, N1, false, false);
+        sms.setStandby(VNID1, N1, VDID1);
+        assertTrue("not backed up", sms.backupsByNetwork.get(VNID1)
+                .get(VDID1).contains(N1));
+        int prev = sms.termMapByNetwork.get(VNID1).get(VDID1).get();
+        sms.setStandby(VNID1, N1, VDID1);
+        assertEquals("term should not change", prev, sms.termMapByNetwork.get(VNID1)
+                .get(VDID1).get());
+
+        //no backup, MASTER
+        put(VNID1, VDID1, N1, true, false);
+        assertNull("expect no MASTER event",
+                   Futures.getUnchecked(sms.setStandby(VNID1, N1, VDID1)).roleInfo().master());
+        assertNull("wrong node", sms.masterMapByNetwork.get(VNID1).get(VDID1));
+
+        //backup, switch
+        sms.masterMapByNetwork.get(VNID1).clear();
+        put(VNID1, VDID1, N1, true, true);
+        put(VNID1, VDID1, N2, false, true);
+        put(VNID1, VDID2, N2, true, true);
+        MastershipEvent event = Futures.getUnchecked(sms.setStandby(VNID1, N1, VDID1));
+        assertEquals("wrong event", MASTER_CHANGED, event.type());
+        assertEquals("wrong master", N2, event.roleInfo().master());
+    }
+
+    //helper to populate master/backup structures
+    private void put(NetworkId networkId, DeviceId dev, NodeId node,
+                     boolean master, boolean backup) {
+        if (master) {
+            sms.masterMapByNetwork
+                    .computeIfAbsent(networkId, k -> new HashMap<>())
+                    .put(dev, node);
+        } else if (backup) {
+            List<NodeId> stbys = sms.backupsByNetwork
+                    .computeIfAbsent(networkId, k -> new HashMap<>())
+                    .getOrDefault(dev, new ArrayList<>());
+            stbys.add(node);
+            sms.backupsByNetwork.get(networkId).put(dev, stbys);
+        }
+
+        sms.termMapByNetwork
+                .computeIfAbsent(networkId, k -> new HashMap<>())
+                .put(dev, new AtomicInteger());
+    }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/resources/domain-config.json b/apps/virtual/app/src/test/resources/domain-config.json
new file mode 100644
index 0000000..beda11a
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/domain-config.json
@@ -0,0 +1,36 @@
+{
+  "domains" : {
+    "cord" : {
+      "basic" : {
+        "name" : "Core Fabric",
+        "applicationName" : "org.onosproject.testdomain",
+        "internalDevices" : [ "of:1" ],
+        "edgePorts" : [ "of:12/1", "of:14/1" ]
+      }
+    },
+    "mpls" : {
+      "basic" : {
+        "name" : "MPLS Core",
+        "applicationName" : "org.onosproject.testdomain",
+        "internalDevices" : [ "of:2" ],
+        "edgePorts" : [ "of:12/2", "of:23/2" ]
+      }
+    },
+    "dc" : {
+      "basic" : {
+        "name" : "Data Center Fabric",
+        "applicationName" : "org.onosproject.testdomain",
+        "internalDevices" : [ "of:3" ],
+        "edgePorts" : [ "of:23/3", "of:34/3" ]
+      }
+    },
+    "optical" : {
+      "basic" : {
+        "name" : "Optical Core",
+        "applicationName" : "org.onosproject.testdomain",
+        "internalDevices" : [ "of:4" ],
+        "edgePorts" : [ "of:14/4", "of:34/4" ]
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/resources/fractal-domain-config.json b/apps/virtual/app/src/test/resources/fractal-domain-config.json
new file mode 100644
index 0000000..521c840
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/fractal-domain-config.json
@@ -0,0 +1,28 @@
+{
+  "domains" : {
+    "domain1" : {
+      "basic" : {
+        "name" : "Domain 1",
+        "applicationName" : "org.onosproject.meshdomain",
+        "internalDevices" : [ "of:0000000000001001", "of:0000000000001002", "of:0000000000001003" ],
+        "edgePorts" : [ "of:0000000000010000/1", "of:0000000003010000/2", "of:0000000002010000/1" ]
+      }
+    },
+    "domain2" : {
+      "basic" : {
+        "name" : "Domain 2",
+        "applicationName" : "org.onosproject.meshdomain",
+        "internalDevices" : [ "of:0000000000002001", "of:0000000000002002", "of:0000000000002003" ],
+        "edgePorts" : [ "of:0000000000020000/1", "of:0000000003020000/1", "of:0000000002010000/2" ]
+      }
+    },
+    "domain3" : {
+      "basic" : {
+        "name" : "Domain 3",
+        "applicationName" : "org.onosproject.meshdomain",
+        "internalDevices" : [ "of:0000000000003001", "of:0000000000003002", "of:0000000000003003" ],
+        "edgePorts" : [ "of:0000000000030000/1", "of:0000000003010000/1", "of:0000000003020000/2" ]
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-tenant.json b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-tenant.json
new file mode 100644
index 0000000..407f9a2
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-tenant.json
@@ -0,0 +1,3 @@
+{
+  "id": "TenantId2"
+}
diff --git a/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-device.json b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-device.json
new file mode 100644
index 0000000..fbd129c
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-device.json
@@ -0,0 +1,4 @@
+{
+  "networkId": "3",
+  "deviceId": "devId2"
+}
diff --git a/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-host.json b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-host.json
new file mode 100644
index 0000000..557dc32
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-host.json
@@ -0,0 +1,16 @@
+{
+  "networkId": "3",
+  "id": "00:11:00:00:00:01/11",
+  "mac": "00:11:00:00:00:01",
+  "vlan": "11",
+  "locations": [
+    {
+      "elementId": "devid1",
+      "port": "100"
+    }
+  ],
+  "ipAddresses": [
+    "10.0.0.1",
+    "10.0.0.2"
+  ]
+}
diff --git a/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-link.json b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-link.json
new file mode 100644
index 0000000..8f04673
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-link.json
@@ -0,0 +1,13 @@
+{
+  "networkId": "3",
+  "src": {
+    "device": "of:devid2",
+    "port": "22" 
+  },
+  "dst": {
+    "device": "of:devid1",
+    "port": "21" 
+  },
+  "type": "VIRTUAL",
+  "state": "ACTIVE"
+}
diff --git a/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-port.json b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-port.json
new file mode 100644
index 0000000..1d60842
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-port.json
@@ -0,0 +1,7 @@
+{
+  "networkId": "3",
+  "deviceId": "dev22",
+  "portNum": "22",
+  "physDeviceId": "dev1",
+  "physPortNum": "1"
+}
