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);
+    }
+}
