diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java
new file mode 100644
index 0000000..320d167
--- /dev/null
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java
@@ -0,0 +1,665 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.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.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Table;
+import javafx.util.Pair;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+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.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.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleListener;
+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.provider.ProviderId;
+import org.onosproject.net.topology.TopologyService;
+import org.osgi.service.component.ComponentContext;
+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 static com.google.common.base.Preconditions.checkNotNull;
+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(immediate = true)
+@Service
+public class DefaultVirtualFlowRuleProvider extends AbstractVirtualProvider
+        implements VirtualFlowRuleProvider {
+
+    private static final int FLOW_RULE_PRIORITY = 10;
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TopologyService topologyService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VirtualNetworkAdminService virtualNetworkAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VirtualProviderRegistryService providerRegistryService;
+
+    InternalRoutingAlgorithm internalRoutingAlgorithm;
+    InternalVirtualFlowRuleManager frm;
+    ApplicationId appId;
+    FlowRuleListener flowRuleListener;
+
+    /**
+     * Creates a provider with the supplied identifier.
+     */
+    public DefaultVirtualFlowRuleProvider() {
+        super(new ProviderId("vnet-flow", "org.onosproject.virtual.vnet-flow"));
+    }
+
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(
+                "org.onosproject.virtual.vnet-flow");
+
+        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);
+        providerRegistryService.unregisterProvider(this);
+    }
+
+    @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);
+
+        //TODO: execute batch mechanism
+    }
+
+    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 virtualize(FlowRule flowRule) {
+        return frm.getVirtualRule(flowRule);
+    }
+
+    private FlowEntry virtualize(FlowEntry flowEntry) {
+        FlowRule vRule = virtualize(flowEntry);
+        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<VirtualPort> vPorts = virtualNetworkAdminService
+                .getVirtualPorts(networkId, flowRule.deviceId());
+
+        PortCriterion portCriterion = ((PortCriterion) flowRule.selector()
+                .getCriterion(Criterion.Type.IN_PORT));
+
+        Set<ConnectPoint> ingressPoints = new HashSet<>();
+        if (portCriterion != null) {
+            PortNumber vInPortNum = portCriterion.port();
+
+            Optional<ConnectPoint> optionalCp =  vPorts.stream()
+                    .filter(v -> v.number().equals(vInPortNum))
+                    .map(v -> v.realizedBy()).findFirst();
+            if (!optionalCp.isPresent()) {
+                log.info("Port {} is not realized yet, in Network {}, Device {}",
+                         vInPortNum, networkId, flowRule.deviceId());
+                return outRules;
+            }
+            ingressPoints.add(optionalCp.get());
+        } else {
+            for (VirtualPort vPort : vPorts) {
+                if (vPort.realizedBy() != null) {
+                    ingressPoints.add(vPort.realizedBy());
+                } else {
+                    log.info("Port {} is not realized yet, in Network {}, " +
+                                     "Device {}",
+                             vPort, networkId, flowRule.deviceId());
+                    return outRules;
+                }
+            }
+        }
+
+        PortNumber vOutPortNum = flowRule.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(v -> v.realizedBy())
+                .findFirst();
+        if (!optionalCpOut.isPresent()) {
+            log.info("Port {} is not realized yet, in Network {}, Device {}",
+                     vOutPortNum, networkId, flowRule.deviceId());
+            return outRules;
+        }
+        ConnectPoint egressPoint = optionalCpOut.get();
+
+        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) {
+            outRules.addAll(generateRules(networkId, ingressPoint, egressPoint,
+                          commonSelector, commonTreatment, flowRule));
+        }
+
+        return outRules;
+    }
+
+    private Set<FlowRule> generateRules(NetworkId networkId,
+                                        ConnectPoint ingressPoint,
+                                        ConnectPoint egressPoint,
+                                    TrafficSelector commonSelector,
+                                    TrafficTreatment commonTreatment,
+                                        FlowRule flowRule) {
+
+        Set<FlowRule> outRules = new HashSet<>();
+
+        if (ingressPoint.deviceId().equals(egressPoint.deviceId())) {
+            //Traffic is handled inside a single physical switch
+            //No tunnel is needed.
+
+            TrafficSelector.Builder selectorBuilder =
+                    DefaultTrafficSelector.builder(commonSelector);
+            selectorBuilder.matchInPort(ingressPoint.port());
+
+            TrafficTreatment.Builder treatmentBuilder =
+                    DefaultTrafficTreatment.builder(commonTreatment);
+            treatmentBuilder.setOutput(egressPoint.port());
+
+            FlowRule.Builder ruleBuilder = DefaultFlowRule.builder();
+            ruleBuilder.fromApp(appId);
+            ruleBuilder.forDevice(ingressPoint.deviceId());
+            ruleBuilder.withSelector(selectorBuilder.build());
+            ruleBuilder.withTreatment(treatmentBuilder.build());
+            ruleBuilder.withPriority(FLOW_RULE_PRIORITY);
+            if (flowRule.isPermanent()) {
+                ruleBuilder.makePermanent();
+            } else {
+                ruleBuilder.makeTemporary(flowRule.timeout());
+            }
+
+            FlowRule rule = ruleBuilder.build();
+            frm.addIngressRule(flowRule, rule, networkId);
+            outRules.add(ruleBuilder.build());
+        } else {
+            //Traffic is handled by multiple physical switches
+            //A tunnel is needed.
+
+            Path internalPath = internalRoutingAlgorithm
+                    .findPath(ingressPoint, egressPoint);
+            checkNotNull(internalPath, "No path between " +
+                    ingressPoint.toString() + " " + egressPoint.toString());
+            ConnectPoint inCp = ingressPoint;
+            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);
+            treatmentBuilder.pushVlan()
+                    .setVlanId(VlanId.vlanId(networkId.id().shortValue()));
+            treatmentBuilder.setOutput(outCp.port());
+
+            FlowRule.Builder ruleBuilder = DefaultFlowRule.builder();
+            ruleBuilder.fromApp(appId);
+            ruleBuilder.forDevice(ingressPoint.deviceId());
+            ruleBuilder.withSelector(selectorBuilder.build());
+            ruleBuilder.withTreatment(treatmentBuilder.build());
+            ruleBuilder.withPriority(FLOW_RULE_PRIORITY);
+            if (flowRule.isPermanent()) {
+                ruleBuilder.makePermanent();
+            } else {
+                ruleBuilder.makeTemporary(flowRule.timeout());
+            }
+
+            FlowRule rule = ruleBuilder.build();
+            frm.addIngressRule(flowRule, rule, networkId);
+            outRules.add(ruleBuilder.build());
+
+            //routing inside tunnel
+            inCp = internalPath.links().get(0).dst();
+
+            if (internalPath.links().size() > 1) {
+                for (Link l : internalPath.links()
+                        .subList(1, internalPath.links().size() - 1)) {
+
+                    outCp = l.src();
+
+                    selectorBuilder = DefaultTrafficSelector
+                            .builder(commonSelector);
+                    selectorBuilder.matchVlanId(
+                            VlanId.vlanId(networkId.id().shortValue()));
+                    selectorBuilder.matchInPort(inCp.port());
+
+                    treatmentBuilder = DefaultTrafficTreatment
+                            .builder(commonTreatment);
+                    treatmentBuilder.setOutput(outCp.port());
+
+                    ruleBuilder = DefaultFlowRule.builder();
+                    ruleBuilder.fromApp(appId);
+                    ruleBuilder.forDevice(inCp.deviceId());
+                    ruleBuilder.withSelector(selectorBuilder.build());
+                    ruleBuilder.withTreatment(treatmentBuilder.build());
+                    if (flowRule.isPermanent()) {
+                        ruleBuilder.makePermanent();
+                    } else {
+                        ruleBuilder.makeTemporary(flowRule.timeout());
+                    }
+
+                    outRules.add(ruleBuilder.build());
+                    inCp = l.dst();
+                }
+            }
+
+            //egress point of tunnel
+            selectorBuilder = DefaultTrafficSelector.builder(commonSelector);
+            selectorBuilder.matchVlanId(
+                    VlanId.vlanId(networkId.id().shortValue()));
+            selectorBuilder.matchInPort(ingressPoint.port());
+
+            treatmentBuilder = DefaultTrafficTreatment.builder(commonTreatment);
+            treatmentBuilder.popVlan();
+            treatmentBuilder.setOutput(egressPoint.port());
+
+            ruleBuilder = DefaultFlowRule.builder();
+            ruleBuilder.fromApp(appId);
+            ruleBuilder.forDevice(egressPoint.deviceId());
+            ruleBuilder.withSelector(selectorBuilder.build());
+            ruleBuilder.withTreatment(treatmentBuilder.build());
+            ruleBuilder.withPriority(FLOW_RULE_PRIORITY);
+            if (flowRule.isPermanent()) {
+                ruleBuilder.makePermanent();
+            } else {
+                ruleBuilder.makeTemporary(flowRule.timeout());
+            }
+
+            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());
+                    ImmutableList.Builder<FlowEntry> builder = ImmutableList.builder();
+                    builder.add(vEntry);
+
+                    VirtualFlowRuleProviderService providerService =
+                            (VirtualFlowRuleProviderService) providerRegistryService
+                                    .getProviderService(networkId,
+                                                        VirtualFlowRuleProvider.class);
+
+                    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());
+
+                    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;
+                }
+            }
+
+            FlowRule vRule = virtualize(entry);
+            FlowEntry vEntry = new DefaultFlowEntry(vRule, entry.state(),
+                                                    entry.life(), entry.packets(),
+                                                    entry.bytes());
+
+            return vEntry;
+        }
+    }
+
+    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 Rules>.*/
+        final Table<NetworkId, DeviceId, Set<FlowRule>> missingFlowRuleTable
+                = 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.newConcurrentMap();
+
+        /** <Physical Flow Rule, Virtual Virtual Flow Rule>.*/
+        final Map<FlowRule, FlowRule> virtualizationMap = Maps.newConcurrentMap();
+
+        private int getFlowRuleCount(NetworkId networkId, DeviceId deviceId) {
+            return flowRuleTable.get(networkId, deviceId).size();
+        }
+
+        private int getMissingFlowCount(NetworkId networkId, DeviceId deviceId) {
+            return missingFlowRuleTable.get(networkId, deviceId).size();
+        }
+
+        private int getFlowEntryCount(NetworkId networkId, DeviceId deviceId) {
+            return flowEntryTable.get(networkId, deviceId).size();
+        }
+
+        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 Set<FlowRule> getMissingRules(NetworkId networkId,
+                                                   DeviceId deviceId) {
+            return missingFlowRuleTable.get(networkId, deviceId);
+        }
+
+        private void addMissingFlowRule(NetworkId networkId, DeviceId deviceId,
+                                 FlowRule flowRule) {
+            Set<FlowRule> set = missingFlowRuleTable.get(networkId, deviceId);
+            if (set == null) {
+                set = Sets.newHashSet();
+                missingFlowRuleTable.put(networkId, deviceId, set);
+            }
+            set.add(flowRule);
+        }
+
+        private void removeMissingFlowRule(NetworkId networkId, DeviceId deviceId,
+                                    FlowRule flowRule) {
+            Set<FlowRule> set = missingFlowRuleTable.get(networkId, deviceId);
+            if (set == null) {
+                return;
+            }
+            set.remove(flowRule);
+        }
+
+        private void addFlowEntry(NetworkId networkId, DeviceId deviceId,
+                                  FlowEntry flowEntry) {
+            Set<FlowEntry> set = flowEntryTable.get(networkId, deviceId);
+            if (set == null) {
+                set = Sets.newHashSet();
+                flowEntryTable.put(networkId, deviceId, set);
+            }
+
+            //Replace old entry with new one
+            set.stream().filter(fe -> fe.exactMatch(flowEntry))
+                    .forEach(set::remove);
+            set.add(flowEntry);
+
+            //Remove old entry from missing flow
+            getMissingRules(networkId, deviceId).stream()
+                    .filter(fr -> fr.exactMatch(flowEntry))
+                    .forEach(fr -> removeMissingFlowRule(networkId, deviceId, fr));
+        }
+
+        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 Set<FlowRule> getAllPhysicalRule() {
+            return ImmutableSet.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 Set<Pair<NetworkId, DeviceId>> getCompletedDevice(boolean
+                                                                  withMissing) {
+
+            Set<Pair<NetworkId, DeviceId>> completed = new HashSet<>();
+
+            for (Table.Cell<NetworkId, DeviceId, Set<FlowRule>> cell
+                    : flowRuleTable.cellSet()) {
+
+                int ruleCount = getFlowRuleCount(cell.getRowKey(),
+                                                 cell.getColumnKey());
+                int missingFlowCount = getMissingFlowCount(cell.getRowKey(),
+                                                           cell.getColumnKey());
+                int entryCount = getFlowEntryCount(cell.getRowKey(),
+                                                   cell.getColumnKey());
+
+                if (withMissing && (ruleCount == missingFlowCount + entryCount)) {
+                    if (ruleCount < entryCount) {
+                        completed.add(new Pair<>(cell.getRowKey(),
+                                                 cell.getColumnKey()));
+                    }
+                } else if (ruleCount == entryCount) {
+                    completed.add(new Pair<>(cell.getRowKey(),
+                                             cell.getColumnKey()));
+                }
+            }
+            return completed;
+        }
+    }
+
+    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/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManager.java
index 40a791f..c822066 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManager.java
@@ -137,7 +137,7 @@
 
     @Override
     public synchronized VirtualProviderService
-    getProviderService(NetworkId networkId, VirtualProvider virtualProvider) {
+    getProviderService(NetworkId networkId, Class<? extends VirtualProvider> providerClass) {
         Set<VirtualProviderService> services = servicesByNetwork.get(networkId);
 
         if (services == null) {
@@ -145,7 +145,7 @@
         }
 
         return services.stream()
-                .filter(s -> getProviderClass(s).isInstance(virtualProvider))
+                .filter(s -> getProviderClass(s).equals(providerClass))
                 .findFirst().get();
     }
 
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java
index 40658bd..0afc6ea 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java
@@ -164,9 +164,9 @@
         vnetFlowRuleService2.deviceInstallers = MoreExecutors.newDirectExecutorService();
 
         providerService1 = (VirtualFlowRuleProviderService)
-                providerRegistryService.getProviderService(vnet1.id(), provider);
+                providerRegistryService.getProviderService(vnet1.id(), VirtualFlowRuleProvider.class);
         providerService2 = (VirtualFlowRuleProviderService)
-                providerRegistryService.getProviderService(vnet2.id(), provider);
+                providerRegistryService.getProviderService(vnet2.id(), VirtualFlowRuleProvider.class);
     }
 
     @After
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java
new file mode 100644
index 0000000..f135464
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java
@@ -0,0 +1,663 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.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.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.core.DefaultApplicationId;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.core.Version;
+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.incubator.net.virtual.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.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.DisjointPath;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+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.FlowRuleListener;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TableStatisticsEntry;
+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.ClusterId;
+import org.onosproject.net.topology.LinkWeight;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyCluster;
+import org.onosproject.net.topology.TopologyGraph;
+import org.onosproject.net.topology.TopologyListener;
+import org.onosproject.net.topology.TopologyService;
+
+import java.util.HashSet;
+import java.util.Map;
+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.virtualNetworkAdminService =
+                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 virtualizeFlowRuleWithInPort() {
+        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 virtualizeFlowRuleWithoutInPort() {
+        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 implements CoreService {
+
+        @Override
+        public Version version() {
+            return null;
+        }
+
+        @Override
+        public Set<ApplicationId> getAppIds() {
+            return null;
+        }
+
+        @Override
+        public ApplicationId getAppId(Short id) {
+            return null;
+        }
+
+        @Override
+        public ApplicationId getAppId(String name) {
+            return null;
+        }
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return new TestApplicationId(1, name);
+        }
+
+        @Override
+        public ApplicationId registerApplication(String name,
+                                                 Runnable preDeactivate) {
+            return null;
+        }
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return null;
+        }
+    }
+
+    private static class TestApplicationId extends DefaultApplicationId {
+        public TestApplicationId(int id, String name) {
+            super(id, name);
+        }
+    }
+
+    private static class TestVirtualNetworkAdminService
+            implements VirtualNetworkAdminService {
+
+        @Override
+        public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
+            return null;
+        }
+
+        @Override
+        public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
+            return ImmutableSet.of(VDEV);
+        }
+
+        @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 ImmutableSet.of(VPORT1, VPORT2);
+        }
+
+        @Override
+        public <T> T get(NetworkId networkId, Class<T> serviceClass) {
+            return null;
+        }
+
+        @Override
+        public ServiceDirectory getServiceDirectory() {
+            return null;
+        }
+
+        @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 removeVirtualPort(NetworkId networkId, DeviceId deviceId,
+                                      PortNumber portNumber) {
+
+        }
+    }
+
+    private static class TestTopologyService implements TopologyService {
+
+        @Override
+        public void addListener(TopologyListener listener) {
+
+        }
+
+        @Override
+        public void removeListener(TopologyListener listener) {
+
+        }
+
+        @Override
+        public Topology currentTopology() {
+            return null;
+        }
+
+        @Override
+        public boolean isLatest(Topology topology) {
+            return false;
+        }
+
+        @Override
+        public TopologyGraph getGraph(Topology topology) {
+            return null;
+        }
+
+        @Override
+        public Set<TopologyCluster> getClusters(Topology topology) {
+            return null;
+        }
+
+        @Override
+        public TopologyCluster getCluster(Topology topology, ClusterId clusterId) {
+            return null;
+        }
+
+        @Override
+        public Set<DeviceId> getClusterDevices(Topology topology,
+                                               TopologyCluster cluster) {
+            return null;
+        }
+
+        @Override
+        public Set<Link> getClusterLinks(Topology topology,
+                                         TopologyCluster cluster) {
+            return null;
+        }
+
+        @Override
+        public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst) {
+            DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
+                                               100, ANNOTATIONS);
+            return ImmutableSet.of(path);
+        }
+
+        @Override
+        public Set<Path> getPaths(Topology topology, DeviceId src,
+                                  DeviceId dst, LinkWeight weight) {
+            DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
+                                               100, ANNOTATIONS);
+            return ImmutableSet.of(path);
+        }
+
+        @Override
+        public Set<DisjointPath> getDisjointPaths(Topology topology,
+                                                  DeviceId src, DeviceId dst) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
+                                                  DeviceId dst, LinkWeight weight) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
+                                                  DeviceId dst,
+                                                  Map<Link, Object> riskProfile) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
+                                                  DeviceId dst, LinkWeight weight,
+                                                  Map<Link, Object> riskProfile) {
+            return null;
+        }
+
+        @Override
+        public boolean isInfrastructure(Topology topology,
+                                        ConnectPoint connectPoint) {
+            return false;
+        }
+
+        @Override
+        public boolean isBroadcastPoint(Topology topology,
+                                        ConnectPoint connectPoint) {
+            return false;
+        }
+    }
+
+    private static class TestFlowRuleService implements FlowRuleService {
+        static Set<FlowRule> ruleCollection = new HashSet<>();
+
+        @Override
+        public void addListener(FlowRuleListener listener) {
+
+        }
+
+        @Override
+        public void removeListener(FlowRuleListener listener) {
+
+        }
+
+        @Override
+        public int getFlowRuleCount() {
+            return ruleCollection.size();
+        }
+
+        @Override
+        public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
+            return ruleCollection.stream()
+                    .filter(r -> r.deviceId().equals(deviceId))
+                    .map(r -> new DefaultFlowEntry(r))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public void applyFlowRules(FlowRule... flowRules) {
+            for (FlowRule rule : flowRules) {
+                ruleCollection.add(rule);
+            }
+        }
+
+        @Override
+        public void purgeFlowRules(DeviceId deviceId) {
+
+        }
+
+        @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);
+        }
+
+        @Override
+        public void removeFlowRulesById(ApplicationId appId) {
+
+        }
+
+        @Override
+        public Iterable<FlowRule> getFlowRulesById(ApplicationId id) {
+            return null;
+        }
+
+        @Override
+        public Iterable<FlowEntry> getFlowEntriesById(ApplicationId id) {
+            return null;
+        }
+
+        @Override
+        public Iterable<FlowRule> getFlowRulesByGroupId(ApplicationId appId,
+                                                        short groupId) {
+            return null;
+        }
+
+        @Override
+        public void apply(FlowRuleOperations ops) {
+
+        }
+
+        @Override
+        public Iterable<TableStatisticsEntry>
+        getFlowTableStatistics(DeviceId deviceId) {
+            return null;
+        }
+    }
+}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java
index f952633..6fb7a8d 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java
@@ -81,7 +81,7 @@
         virtualProviderManager.registerProviderService(NETWORK_ID1, providerService1);
 
         assertEquals(providerService1,
-                     virtualProviderManager.getProviderService(NETWORK_ID1, provider1));
+                     virtualProviderManager.getProviderService(NETWORK_ID1, TestProvider1.class));
     }
 
     private class TestProvider1 extends AbstractVirtualProvider {
