diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/DistributedTeTopologyStore.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/DistributedTeTopologyStore.java
new file mode 100644
index 0000000..e3284b3
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/DistributedTeTopologyStore.java
@@ -0,0 +1,1413 @@
+/*
+ * 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.tetopology.management.impl;
+
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_UPDATED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_UPDATED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_UPDATED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_UPDATED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_UPDATED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_UPDATED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.BitSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.net.DeviceId;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.AtomicCounter;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.tetopology.management.api.CommonTopologyData;
+import org.onosproject.tetopology.management.api.DefaultNetwork;
+import org.onosproject.tetopology.management.api.DefaultTeTopologies;
+import org.onosproject.tetopology.management.api.DefaultTeTopology;
+import org.onosproject.tetopology.management.api.EncodingType;
+import org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.LongValue;
+import org.onosproject.tetopology.management.api.Network;
+import org.onosproject.tetopology.management.api.OptimizationType;
+import org.onosproject.tetopology.management.api.ProviderClientId;
+import org.onosproject.tetopology.management.api.SwitchingType;
+import org.onosproject.tetopology.management.api.TeConstants;
+import org.onosproject.tetopology.management.api.TeStatus;
+import org.onosproject.tetopology.management.api.TeTopologies;
+import org.onosproject.tetopology.management.api.TeTopology;
+import org.onosproject.tetopology.management.api.TeTopologyEvent;
+import org.onosproject.tetopology.management.api.TeTopologyEvent.Type;
+import org.onosproject.tetopology.management.api.TeTopologyId;
+import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetopology.management.api.TeUtils;
+import org.onosproject.tetopology.management.api.link.AsNumber;
+import org.onosproject.tetopology.management.api.link.CommonLinkData;
+import org.onosproject.tetopology.management.api.link.DefaultNetworkLink;
+import org.onosproject.tetopology.management.api.link.DefaultTeLink;
+import org.onosproject.tetopology.management.api.link.ElementType;
+import org.onosproject.tetopology.management.api.link.ExternalLink;
+import org.onosproject.tetopology.management.api.link.Label;
+import org.onosproject.tetopology.management.api.link.LinkBandwidth;
+import org.onosproject.tetopology.management.api.link.NetworkLink;
+import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
+import org.onosproject.tetopology.management.api.link.OduResource;
+import org.onosproject.tetopology.management.api.link.PathElement;
+import org.onosproject.tetopology.management.api.link.TeIpv4;
+import org.onosproject.tetopology.management.api.link.TeIpv6;
+import org.onosproject.tetopology.management.api.link.TeLink;
+import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
+import org.onosproject.tetopology.management.api.link.TeLinkTpKey;
+import org.onosproject.tetopology.management.api.link.TePathAttributes;
+import org.onosproject.tetopology.management.api.link.TunnelProtectionType;
+import org.onosproject.tetopology.management.api.link.UnderlayAbstractPath;
+import org.onosproject.tetopology.management.api.link.UnderlayBackupPath;
+import org.onosproject.tetopology.management.api.link.UnderlayPath;
+import org.onosproject.tetopology.management.api.link.UnderlayPrimaryPath;
+import org.onosproject.tetopology.management.api.link.UnnumberedLink;
+import org.onosproject.tetopology.management.api.node.CommonNodeData;
+import org.onosproject.tetopology.management.api.node.ConnectivityMatrix;
+import org.onosproject.tetopology.management.api.node.ConnectivityMatrixKey;
+import org.onosproject.tetopology.management.api.node.DefaultNetworkNode;
+import org.onosproject.tetopology.management.api.node.DefaultTeNode;
+import org.onosproject.tetopology.management.api.node.DefaultTerminationPoint;
+import org.onosproject.tetopology.management.api.node.DefaultTunnelTerminationPoint;
+import org.onosproject.tetopology.management.api.node.LocalLinkConnectivity;
+import org.onosproject.tetopology.management.api.node.NetworkNode;
+import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
+import org.onosproject.tetopology.management.api.node.NodeTpKey;
+import org.onosproject.tetopology.management.api.node.TeNode;
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+import org.onosproject.tetopology.management.api.node.TerminationPoint;
+import org.onosproject.tetopology.management.api.node.TerminationPointKey;
+import org.onosproject.tetopology.management.api.node.TtpKey;
+import org.onosproject.tetopology.management.api.node.TunnelTerminationPoint;
+import org.slf4j.Logger;
+
+import com.esotericsoftware.kryo.serializers.JavaSerializer;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Implementation of the TE network store.
+ */
+@Component(immediate = true)
+@Service
+public class DistributedTeTopologyStore
+    extends AbstractStore<TeTopologyEvent, TeTopologyStoreDelegate>
+    implements TeTopologyStore {
+    private static final String STORE_NAME = "TE_NETWORK_TOPOLOGY_STORE";
+    private static final String TETOPOLOGYKEY_INTERNALTETOPOLOGY = "TeTopologyKey-InternalTeTopology";
+    private static final String NETWORKID_NETWORK = "NetworkId-Network";
+    private static final String TENODEKEY_INTERNALTENODE = "TeNodeKey-InternalTeNode";
+    private static final String CONNMATRIXKEY_CONNECTIVITYMATRIX = "ConnMatrixKey-ConnectivityMatrix";
+    private static final String NETWORKNODEKEY_INTERNALNETWORKNODE = "NetworkNodeKey-InternalNetworkNode";
+    private static final String TELINKGLOBALKEY_INTERNALTELINK = "TeLinkGlobalKey-InternalTeLink";
+    private static final String NETWORKLINKKEY_INTERNALNETWORKLINK = "NetworkLinkKey-InternalNetworkLink";
+    private static final String TPKEY_INTERNALTERMINATIONPOINT = "tpKey-InternalTerminationPoint";
+    private static final String TELINKTPGLOBALKEY_TERMINATIONPOINTKEY = "TeLinkGlobalKey-TerminationPointKey";
+    private static final String TTPKEY_TUNNELTERMINATIONPOINT = "TtpKey-TunnelTerminationPoint";
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+    // Track TE topologies by TE Topology key
+    private ConsistentMap<TeTopologyKey, InternalTeTopology> teTopologyConsistentMap;
+    private Map<TeTopologyKey, InternalTeTopology> teTopologyMap;
+    private AtomicCounter nextTeTopologyId;
+     // Listener for te topology events
+    private final MapEventListener<TeTopologyKey, InternalTeTopology> teTopologyListener =
+            new InternalTeTopologyListener();
+    // Track networks by network Id
+    private ConsistentMap<KeyId, InternalNetwork> networkConsistentMap;
+    private Map<KeyId, InternalNetwork> networkMap;
+    // Listener for network events
+    private final MapEventListener<KeyId, InternalNetwork> networkListener =
+            new InternalNetworkListener();
+    // Track TE nodes by TE node key
+    private ConsistentMap<TeNodeKey, InternalTeNode> teNodeConsistentMap;
+    private Map<TeNodeKey, InternalTeNode> teNodeMap;
+    // Track ConnectivityMatrix by its key
+    private ConsistentMap<ConnectivityMatrixKey, ConnectivityMatrix> connMatrixConsistentMap;
+    private Map<ConnectivityMatrixKey, ConnectivityMatrix> connMatrixMap;
+    // Track Tunnel Termination Points by its key
+    private ConsistentMap<TtpKey, TunnelTerminationPoint> ttpConsistentMap;
+    private Map<TtpKey, TunnelTerminationPoint> ttpMap;
+    // Listener for TE node events
+    private final MapEventListener<TeNodeKey, InternalTeNode> teNodeListener =
+            new InternalTeNodeListener();
+    // Track network nodes by network node key
+    private ConsistentMap<NetworkNodeKey, InternalNetworkNode> networkNodeConsistentMap;
+    private Map<NetworkNodeKey, InternalNetworkNode> networkNodeMap;
+    // Listener for network node events
+    private final MapEventListener<NetworkNodeKey, InternalNetworkNode> networkNodeListener =
+            new InternalNetworkNodeListener();
+    // Track TE links by its key
+    private ConsistentMap<TeLinkTpGlobalKey, InternalTeLink> teLinkConsistentMap;
+    private Map<TeLinkTpGlobalKey, InternalTeLink> teLinkMap;
+    // Listener for te link events
+    private final MapEventListener<TeLinkTpGlobalKey, InternalTeLink> teLinkListener =
+        new InternalTeLinkListener();
+    // Track network links by network link key
+    private ConsistentMap<NetworkLinkKey, InternalNetworkLink> networkLinkConsistentMap;
+    private Map<NetworkLinkKey, InternalNetworkLink> networkLinkMap;
+    // Listener for network link events
+    private final MapEventListener<NetworkLinkKey, InternalNetworkLink> networkLinkListener =
+            new InternalNetworkLinkListener();
+    // Track Termination points by termination point key
+    private ConsistentMap<TerminationPointKey, InternalTerminationPoint> tpConsistentMap;
+    private Map<TerminationPointKey, InternalTerminationPoint> tpMap;
+    // Track termination point keys by TE termination point Key
+    private ConsistentMap<TeLinkTpGlobalKey, TerminationPointKey> tpKeyConsistentMap;
+    private Map<TeLinkTpGlobalKey, TerminationPointKey> tpKeyMap;
+    private BlockingQueue<TeTopologyMapEvent> mapEventQueue;
+    private static final Serializer TETOPOLOGY_SERIALIZER = Serializer
+            .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
+                    .register(TeTopologyKey.class)
+                    .register(ProviderClientId.class)
+                    .register(TeNodeKey.class)
+                    .register(TeLinkTpGlobalKey.class)
+                    .register(CommonTopologyData.class)
+                    .register(KeyId.class)
+                    .register(OptimizationType.class)
+                    .register(new JavaSerializer(), BitSet.class)
+                    .register(InternalTeTopology.class)
+                    .register(InternalNetwork.class)
+                    .register(InternalTerminationPoint.class)
+                    .register(InternalTeNode.class)
+                    .register(InternalNetworkNode.class)
+                    .register(CommonNodeData.class)
+                    .register(ConnectivityMatrixKey.class)
+                    .register(ConnectivityMatrix.class)
+                    .register(TtpKey.class)
+                    .register(NetworkNodeKey.class)
+                    .register(TeStatus.class)
+                    .register(ElementType.class)
+                    .register(TeIpv4.class)
+                    .register(TeIpv6.class)
+                    .register(AsNumber.class)
+                    .register(Label.class)
+                    .register(UnnumberedLink.class)
+                    .register(InternalTeLink.class)
+                    .register(InternalNetworkLink.class)
+                    .register(TeLinkTpKey.class)
+                    .register(NetworkLinkKey.class)
+                    .register(NodeTpKey.class)
+                    .register(CommonLinkData.class)
+                    .register(SwitchingType.class)
+                    .register(EncodingType.class)
+                    .register(ExternalLink.class)
+                    .register(UnderlayPath.class)
+                    .register(LinkBandwidth.class)
+                    .register(OduResource.class)
+                    .register(PathElement.class)
+                    .register(UnderlayAbstractPath.class)
+                    .register(UnderlayBackupPath.class)
+                    .register(UnderlayPrimaryPath.class)
+                    .register(TePathAttributes.class)
+                    .register(TerminationPoint.class)
+                    .register(TunnelTerminationPoint.class)
+                    .register(DefaultTunnelTerminationPoint.class)
+                    .register(TerminationPointKey.class)
+                    .register(TunnelProtectionType.class)
+                    .register(LongValue.class)
+                    .register(LocalLinkConnectivity.class)
+                    .build());
+
+    /**
+     * Distributed network store service activate method.
+     */
+    @Activate
+    public void activate() {
+        teTopologyConsistentMap = storageService
+                .<TeTopologyKey, InternalTeTopology>consistentMapBuilder()
+                .withSerializer(TETOPOLOGY_SERIALIZER)
+                .withName(TETOPOLOGYKEY_INTERNALTETOPOLOGY)
+                .withRelaxedReadConsistency()
+                .build();
+        teTopologyConsistentMap.addListener(teTopologyListener);
+        teTopologyMap = teTopologyConsistentMap.asJavaMap();
+        networkConsistentMap = storageService
+                .<KeyId, InternalNetwork>consistentMapBuilder()
+                .withSerializer(TETOPOLOGY_SERIALIZER)
+                .withName(NETWORKID_NETWORK)
+                .withRelaxedReadConsistency()
+                .build();
+        networkConsistentMap.addListener(networkListener);
+        networkMap = networkConsistentMap.asJavaMap();
+        teNodeConsistentMap = storageService
+                .<TeNodeKey, InternalTeNode>consistentMapBuilder()
+                .withSerializer(TETOPOLOGY_SERIALIZER)
+                .withName(TENODEKEY_INTERNALTENODE)
+                .withRelaxedReadConsistency()
+                .build();
+        teNodeConsistentMap.addListener(teNodeListener);
+        teNodeMap = teNodeConsistentMap.asJavaMap();
+        connMatrixConsistentMap = storageService
+                 .<ConnectivityMatrixKey, ConnectivityMatrix>consistentMapBuilder()
+                 .withSerializer(TETOPOLOGY_SERIALIZER)
+                 .withName(CONNMATRIXKEY_CONNECTIVITYMATRIX)
+                 .withRelaxedReadConsistency()
+                 .build();
+        connMatrixMap = connMatrixConsistentMap.asJavaMap();
+        networkNodeConsistentMap = storageService
+                 .<NetworkNodeKey, InternalNetworkNode>consistentMapBuilder()
+                 .withSerializer(TETOPOLOGY_SERIALIZER)
+                 .withName(NETWORKNODEKEY_INTERNALNETWORKNODE)
+                 .withRelaxedReadConsistency()
+                 .build();
+        networkNodeConsistentMap.addListener(networkNodeListener);
+        networkNodeMap = networkNodeConsistentMap.asJavaMap();
+        teLinkConsistentMap = storageService
+                 .<TeLinkTpGlobalKey, InternalTeLink>consistentMapBuilder()
+                 .withSerializer(TETOPOLOGY_SERIALIZER)
+                 .withName(TELINKGLOBALKEY_INTERNALTELINK)
+                 .withRelaxedReadConsistency()
+                 .build();
+        teLinkConsistentMap.addListener(teLinkListener);
+        teLinkMap = teLinkConsistentMap.asJavaMap();
+        networkLinkConsistentMap = storageService
+                 .<NetworkLinkKey, InternalNetworkLink>consistentMapBuilder()
+                 .withSerializer(TETOPOLOGY_SERIALIZER)
+                 .withName(NETWORKLINKKEY_INTERNALNETWORKLINK)
+                 .withRelaxedReadConsistency()
+                 .build();
+        networkLinkConsistentMap.addListener(networkLinkListener);
+        networkLinkMap = networkLinkConsistentMap.asJavaMap();
+        tpConsistentMap = storageService
+                 .<TerminationPointKey, InternalTerminationPoint>consistentMapBuilder()
+                 .withSerializer(TETOPOLOGY_SERIALIZER)
+                 .withName(TPKEY_INTERNALTERMINATIONPOINT)
+                 .withRelaxedReadConsistency()
+                 .build();
+        tpMap = tpConsistentMap.asJavaMap();
+        tpKeyConsistentMap = storageService
+                  .<TeLinkTpGlobalKey, TerminationPointKey>consistentMapBuilder()
+                  .withSerializer(TETOPOLOGY_SERIALIZER)
+                  .withName(TELINKTPGLOBALKEY_TERMINATIONPOINTKEY)
+                  .withRelaxedReadConsistency()
+                  .build();
+        tpKeyMap = tpKeyConsistentMap.asJavaMap();
+        ttpConsistentMap = storageService
+                  .<TtpKey, TunnelTerminationPoint>consistentMapBuilder()
+                  .withSerializer(TETOPOLOGY_SERIALIZER)
+                  .withName(TTPKEY_TUNNELTERMINATIONPOINT)
+                  .withRelaxedReadConsistency()
+                  .build();
+        ttpMap = ttpConsistentMap.asJavaMap();
+
+        nextTeTopologyId = storageService.getAtomicCounter("COUNTER_NAME");
+        log.info("Started");
+    }
+
+    /**
+     * Distributed network store service deactivate method.
+     */
+    @Deactivate
+    public void deactivate() {
+        teTopologyConsistentMap.removeListener(teTopologyListener);
+        teTopologyConsistentMap.destroy();
+        teTopologyMap.clear();
+        networkConsistentMap.removeListener(networkListener);
+        networkConsistentMap.destroy();
+        networkMap.clear();
+        teNodeConsistentMap.removeListener(teNodeListener);
+        teNodeConsistentMap.destroy();
+        teNodeMap.clear();
+        connMatrixConsistentMap.destroy();
+        connMatrixMap.clear();
+        networkNodeConsistentMap.destroy();
+        networkNodeConsistentMap.removeListener(networkNodeListener);
+        networkNodeMap.clear();
+        teLinkConsistentMap.removeListener(teLinkListener);
+        teLinkConsistentMap.destroy();
+        teLinkMap.clear();
+        networkLinkConsistentMap.destroy();
+        networkLinkConsistentMap.removeListener(networkLinkListener);
+        networkLinkMap.clear();
+        tpConsistentMap.destroy();
+        tpMap.clear();
+        tpKeyConsistentMap.destroy();
+        tpKeyMap.clear();
+        ttpConsistentMap.destroy();
+        ttpMap.clear();
+        log.info("Stopped");
+    }
+
+    /**
+     * Listener class to map listener map events to the TETOPOLOGY events.
+     */
+    private class InternalTeTopologyListener implements MapEventListener<TeTopologyKey, InternalTeTopology> {
+        @Override
+        public void event(MapEvent<TeTopologyKey, InternalTeTopology> event) {
+            Type type = null;
+            switch (event.type()) {
+            case INSERT:
+                type = TE_TOPOLOGY_ADDED;
+                break;
+            case UPDATE:
+                if (event.newValue().value().childUpdate()) {
+                    // Masked by the child events (e.g. Removal)
+                    break;
+                }
+                type = TE_TOPOLOGY_UPDATED;
+                break;
+            case REMOVE:
+                type = TE_TOPOLOGY_REMOVED;
+                break;
+            default:
+                log.error("Unsupported event type: {}", event.type());
+            }
+            if (type != null) {
+                TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+                mapEvent.setTeTopologyKey(event.key());
+                try {
+                    mapEventQueue.put(mapEvent);
+                } catch (InterruptedException e) {
+                    log.warn("Unable to queue event {} ", mapEvent, e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Listener class to map listener map events to the network events.
+     */
+    private class InternalNetworkListener implements MapEventListener<KeyId, InternalNetwork> {
+        @Override
+        public void event(MapEvent<KeyId, InternalNetwork> event) {
+            Type type = null;
+            switch (event.type()) {
+            case INSERT:
+                type = NETWORK_ADDED;
+                break;
+            case UPDATE:
+                if (event.newValue().value().childUpdate()) {
+                    // Masked by the child events (e.g. Removal)
+                    break;
+                }
+                type = NETWORK_UPDATED;
+                break;
+            case REMOVE:
+                type = NETWORK_REMOVED;
+                break;
+            default:
+                log.error("Unsupported event type: {}", event.type());
+            }
+            if (type != null) {
+                TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+                mapEvent.setNetworkKey(event.key());
+                try {
+                    mapEventQueue.put(mapEvent);
+                } catch (InterruptedException e) {
+                    log.warn("Unable to queue event {} ", mapEvent, e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Listener class to map listener map events to the TENODE events.
+     */
+    private class InternalTeNodeListener implements MapEventListener<TeNodeKey, InternalTeNode> {
+        @Override
+        public void event(MapEvent<TeNodeKey, InternalTeNode> event) {
+            // Event should be ignored when the topology is not there.
+            if (teTopologyMap.get(event.key().teTopologyKey()) == null) {
+                return;
+            }
+            Type type = null;
+            switch (event.type()) {
+            case INSERT:
+                if (event.newValue().value().parentUpdate()) {
+                    // Masked by the parent event (e.g. Add)
+                    break;
+                }
+                type = TE_NODE_ADDED;
+                break;
+            case UPDATE:
+                if (event.newValue().value().childUpdate() ||
+                        event.newValue().value().parentUpdate()) {
+                    // Masked by the child event (e.g. Removal) or parent event
+                    break;
+                }
+                type = TE_NODE_UPDATED;
+                break;
+            case REMOVE:
+                type = TE_NODE_REMOVED;
+                break;
+            default:
+                log.error("Unsupported event type: {}", event.type());
+            }
+            if (type != null) {
+                TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+                mapEvent.setTeNodeKey(event.key());
+                try {
+                    mapEventQueue.put(mapEvent);
+                } catch (InterruptedException e) {
+                    log.warn("Unable to queue event {} ", mapEvent, e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Listener class to map listener map events to the NETWORK NODE events.
+     */
+    private class InternalNetworkNodeListener implements MapEventListener<NetworkNodeKey, InternalNetworkNode> {
+        @Override
+        public void event(MapEvent<NetworkNodeKey, InternalNetworkNode> event) {
+            // Event should be ignored when the network is not there.
+            if (networkMap.get(event.key().networkId()) == null) {
+                return;
+            }
+            Type type = null;
+            switch (event.type()) {
+            case INSERT:
+                if (event.newValue().value().parentUpdate()) {
+                    // Masked by the parent event (e.g. Add)
+                    break;
+                }
+                type = NODE_ADDED;
+                break;
+            case UPDATE:
+                if (event.newValue().value().childUpdate() ||
+                        event.newValue().value().parentUpdate()) {
+                    // Masked by the child event (e.g. Removal) or parent event
+                    break;
+                }
+                type = NODE_UPDATED;
+                break;
+            case REMOVE:
+                type = NODE_REMOVED;
+                break;
+            default:
+                log.error("Unsupported event type: {}", event.type());
+            }
+            if (type != null) {
+                TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+                mapEvent.setNetworkNodeKey(event.key());
+                try {
+                    mapEventQueue.put(mapEvent);
+                } catch (InterruptedException e) {
+                    log.warn("Unable to queue event {} ", mapEvent, e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Listener class to map listener map events to the TELINK events.
+     */
+    private class InternalTeLinkListener implements MapEventListener<TeLinkTpGlobalKey, InternalTeLink> {
+        @Override
+        public void event(MapEvent<TeLinkTpGlobalKey, InternalTeLink> event) {
+            // Event should be ignored when the topology or locol node is not there.
+            if (teTopologyMap.get(event.key().teTopologyKey()) == null ||
+                    teNodeMap.get(event.key().teNodeKey()) == null) {
+                return;
+            }
+            Type type = null;
+            switch (event.type()) {
+            case INSERT:
+                if (event.newValue().value().parentUpdate()) {
+                    // Masked by the parent event (e.g. Add)
+                    break;
+                }
+                type = TE_LINK_ADDED;
+                break;
+            case UPDATE:
+                if (event.newValue().value().parentUpdate()) {
+                    // Masked by parent event
+                    break;
+                }
+                type = TE_LINK_UPDATED;
+                break;
+            case REMOVE:
+                type = TE_LINK_REMOVED;
+                break;
+            default:
+                log.error("Unsupported event type: {}", event.type());
+            }
+            if (type != null) {
+                TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+                mapEvent.setTeLinkKey(event.key());
+                try {
+                    mapEventQueue.put(mapEvent);
+                } catch (InterruptedException e) {
+                    log.warn("Unable to queue event {} ", mapEvent, e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Listener class to map listener map events to the NETWORK LINK events.
+     */
+    private class InternalNetworkLinkListener implements MapEventListener<NetworkLinkKey, InternalNetworkLink> {
+        @Override
+        public void event(MapEvent<NetworkLinkKey, InternalNetworkLink> event) {
+            // Event should be ignored when the network is not there.
+            if (networkMap.get(event.key().networkId()) == null) {
+                return;
+            }
+            Type type = null;
+            switch (event.type()) {
+            case INSERT:
+                if (event.newValue().value().parentUpdate()) {
+                    // Masked by the parent event (e.g. Add)
+                    break;
+                }
+                type = LINK_ADDED;
+                break;
+            case UPDATE:
+                if (event.newValue().value().parentUpdate()) {
+                    // Masked by the child event (e.g. Removal) or parent event
+                    break;
+                }
+                type = LINK_UPDATED;
+                break;
+            case REMOVE:
+                type = LINK_REMOVED;
+                break;
+            default:
+                log.error("Unsupported event type: {}", event.type());
+            }
+            if (type != null) {
+                TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+                mapEvent.setNetworkLinkKey(event.key());
+                try {
+                    mapEventQueue.put(mapEvent);
+                } catch (InterruptedException e) {
+                    log.warn("Unable to queue event {} ", mapEvent, e);
+                }
+            }
+        }
+    }
+
+    @Override
+    public TeTopologies teTopologies() {
+        Map<TeTopologyKey, TeTopology> teTopologies = Maps.newHashMap();
+        if (MapUtils.isNotEmpty(teTopologyMap)) {
+            for (TeTopologyKey key  : teTopologyMap.keySet()) {
+                teTopologies.put(key, teTopology(key));
+            }
+        }
+        return new DefaultTeTopologies(STORE_NAME, teTopologies);
+    }
+
+    private TeTopology teTopology(TeTopologyKey topologyId,
+                                  InternalTeTopology intTopology) {
+        if (intTopology == null) {
+            return null;
+        }
+        Map<Long, TeNode> teNodes = null;
+        if (CollectionUtils.isNotEmpty(intTopology.teNodeKeys())) {
+            teNodes = Maps.newHashMap();
+            for (TeNodeKey key : intTopology.teNodeKeys()) {
+                teNodes.put(key.teNodeId(), teNode(key));
+            }
+        }
+        Map<TeLinkTpKey, TeLink> teLinks = null;
+        if (CollectionUtils.isNotEmpty(intTopology.teLinkKeys())) {
+            teLinks = Maps.newHashMap();
+            for (TeLinkTpGlobalKey key : intTopology.teLinkKeys()) {
+                teLinks.put(key.teLinkTpKey(), teLink(key));
+            }
+        }
+        return new DefaultTeTopology(topologyId, teNodes, teLinks,
+                intTopology.teTopologyId(), intTopology.topologyData());
+    }
+
+    @Override
+    public TeTopology teTopology(TeTopologyKey topologyId) {
+        InternalTeTopology intTopology = teTopologyMap.get(topologyId);
+        return teTopology(topologyId, intTopology);
+    }
+
+    private void removeTopologyeMapEntrys(InternalTeTopology curTopology) {
+        // Remove TE nodes
+        if (CollectionUtils.isNotEmpty(curTopology.teNodeKeys())) {
+            for (TeNodeKey key : curTopology.teNodeKeys()) {
+                removeTeNode(key, true);
+            }
+        }
+        // Remove TE Links
+        if (CollectionUtils.isNotEmpty(curTopology.teLinkKeys())) {
+            for (TeLinkTpGlobalKey key : curTopology.teLinkKeys()) {
+                removeTeLink(key, true);
+            }
+        }
+    }
+
+    @Override
+    public void updateTeTopology(TeTopology teTopology) {
+        InternalTeTopology curTopology = teTopologyMap.get(teTopology.teTopologyId());
+        // Update TE nodes
+        List<NetworkNodeKey> nodeIds = null;
+        if (MapUtils.isNotEmpty(teTopology.teNodes())) {
+            nodeIds = Lists.newArrayList();
+            for (Map.Entry<Long, TeNode> entry : teTopology.teNodes().entrySet()) {
+                TeNodeKey teNodeKey = new TeNodeKey(teTopology.teTopologyId(), entry.getKey());
+                NetworkNodeKey nodeKey = TeMgrUtil.networkNodeKey(teNodeKey);
+                updateTeNode(teNodeKey, entry.getValue(), true, true, nodeKey);
+                nodeIds.add(nodeKey);
+            }
+        }
+        // Update TE links
+        List<NetworkLinkKey> linkIds = null;
+        if (MapUtils.isNotEmpty(teTopology.teLinks())) {
+            linkIds = Lists.newArrayList();
+            for (Map.Entry<TeLinkTpKey, TeLink> entry : teTopology.teLinks().entrySet()) {
+                TeLinkTpGlobalKey teLinkKey = new TeLinkTpGlobalKey(teTopology.teTopologyId(),
+                        entry.getKey());
+                NetworkLinkKey linkKey = TeMgrUtil.networkLinkKey(teLinkKey);
+                updateTeLink(teLinkKey, entry.getValue(), true, true, linkKey);
+                linkIds.add(linkKey);
+            }
+        }
+        // Finally Update teTopologyMap
+        InternalTeTopology newTopology = new InternalTeTopology(teTopology);
+        teTopologyMap.put(teTopology.teTopologyId(), newTopology);
+
+        if (curTopology == null) {
+            // New topology, update networkMap
+            InternalNetwork intNetwork = new InternalNetwork();
+            intNetwork.setServerProvided(false);
+            intNetwork.setTeTopologyKey(teTopology.teTopologyId());
+            intNetwork.setNodeIds(nodeIds);
+            intNetwork.setLinkIds(linkIds);
+            networkMap.put(teTopology.networkId(), intNetwork);
+        }
+    }
+
+    @Override
+    public void removeTeTopology(TeTopologyKey topologyId) {
+        // Remove it from teTopologyMap
+        InternalTeTopology topology = teTopologyMap.remove(topologyId);
+        if (topology != null) {
+            removeTopologyeMapEntrys(topology);
+            // Remove it from networkMap;
+            networkMap.remove(topology.topologyData().networkId());
+        }
+    }
+
+    @Override
+    public List<Network> networks() {
+        if (MapUtils.isEmpty(networkMap)) {
+            return null;
+        }
+        List<Network> networks = Lists.newArrayList();
+        for (KeyId networkId : networkMap.keySet()) {
+            networks.add(network(networkId));
+        }
+        return networks;
+    }
+
+    private Network network(KeyId networkId, InternalNetwork curNetwork) {
+        if (curNetwork == null) {
+            return null;
+        }
+        List<KeyId> supportingNetworkIds = curNetwork.supportingNetworkIds();
+        Map<KeyId, NetworkNode> nodes = null;
+        if (CollectionUtils.isNotEmpty(curNetwork.nodeIds())) {
+            nodes = Maps.newHashMap();
+            for (NetworkNodeKey key : curNetwork.nodeIds()) {
+                nodes.put(key.nodeId(), networkNode(key));
+            }
+        }
+        Map<KeyId, NetworkLink> links = null;
+        if (CollectionUtils.isNotEmpty(curNetwork.linkIds())) {
+            links = Maps.newHashMap();
+            for (NetworkLinkKey key : curNetwork.linkIds()) {
+                links.put(key.linkId(), networkLink(key));
+            }
+        }
+        TeTopologyId topologyId = null;
+        DeviceId ownerId = null;
+        if (curNetwork.teTopologyKey() != null &&
+                teTopologyMap.get(curNetwork.teTopologyKey()) != null) {
+            topologyId = new TeTopologyId(curNetwork.teTopologyKey().providerId(),
+                                          curNetwork.teTopologyKey().clientId(),
+                                          teTopologyMap
+                                                  .get(curNetwork
+                                                          .teTopologyKey())
+                                                  .teTopologyId());
+            ownerId = teTopologyMap.get(curNetwork.teTopologyKey())
+                    .topologyData().ownerId();
+
+        }
+        return new DefaultNetwork(networkId, supportingNetworkIds, nodes, links,
+                                  topologyId, curNetwork.serverProvided(), ownerId);
+    }
+
+    @Override
+    public Network network(KeyId networkId) {
+        InternalNetwork curNetwork = networkMap.get(networkId);
+        return network(networkId, curNetwork);
+    }
+
+    private void removeNetworkMapEntrys(InternalNetwork curNetwork, boolean teRemove) {
+        // Remove TE nodes
+        if (CollectionUtils.isNotEmpty(curNetwork.nodeIds())) {
+            for (NetworkNodeKey key : curNetwork.nodeIds()) {
+                removeNetworkNode(key, teRemove);
+            }
+        }
+        // Remove TE Links
+        if (CollectionUtils.isNotEmpty(curNetwork.linkIds())) {
+            for (NetworkLinkKey key : curNetwork.linkIds()) {
+                removeNetworkLink(key, teRemove);
+            }
+        }
+    }
+
+    private TeTopologyKey newTeTopologyKey(TeTopologyId teTopologyId) {
+        long idValue;
+        try {
+            idValue = Long.parseLong(teTopologyId.topologyId());
+        } catch (NumberFormatException e) {
+            // Can't get the long value from the string.
+            // Use an assigned id value from local id pool,
+            // Ideally id should be assigned per provider base.
+            idValue = nextTeTopologyId();
+        }
+        return new TeTopologyKey(teTopologyId.providerId(), teTopologyId.clientId(), idValue);
+    }
+
+    @Override
+    public void updateNetwork(Network network) {
+        InternalNetwork curNetwork = networkMap.get(network.networkId());
+        TeTopologyKey topoKey = null;
+        if (network.teTopologyId() != null) {
+            topoKey = newTeTopologyKey(network.teTopologyId());
+        }
+        // Update TE nodes
+        List<TeNodeKey> teNodeKeys = null;
+        if (MapUtils.isNotEmpty(network.nodes())) {
+            teNodeKeys = Lists.newArrayList();
+            for (Map.Entry<KeyId, NetworkNode> entry : network.nodes().entrySet()) {
+                NetworkNodeKey nodeKey = new NetworkNodeKey(network.networkId(), entry.getKey());
+                TeNodeKey teNodeKey = null;
+                if (topoKey != null && entry.getValue().teNode() != null) {
+                    teNodeKey = new TeNodeKey(topoKey, entry.getValue().teNode().teNodeId());
+                }
+                updateNetworkNode(nodeKey, entry.getValue(), true, false, teNodeKey);
+                teNodeKeys.add(teNodeKey);
+            }
+        }
+        // Update TE links
+        List<TeLinkTpGlobalKey> teLinkKeys = null;
+        if (MapUtils.isNotEmpty(network.links())) {
+            teLinkKeys = Lists.newArrayList();
+            for (Map.Entry<KeyId, NetworkLink> entry : network.links().entrySet()) {
+                NetworkLinkKey linkKey = new NetworkLinkKey(network.networkId(), entry.getKey());
+                TeLinkTpGlobalKey teLinkKey = null;
+                if (topoKey != null && entry.getValue().teLink() != null) {
+                    teLinkKey = new TeLinkTpGlobalKey(topoKey, entry.getValue().teLink().teLinkKey());
+                }
+                updateNetworkLink(linkKey, entry.getValue(), true, false, teLinkKey);
+                teLinkKeys.add(teLinkKey);
+            }
+        }
+
+        // New network, update TE Topology first
+        if (curNetwork == null) {
+            InternalTeTopology intTopo = new InternalTeTopology(network.teTopologyId().topologyId());
+            intTopo.setTeNodeKeys(teNodeKeys);
+            intTopo.setTeLinkKeys(teLinkKeys);
+            BitSet flags = new BitSet(TeConstants.FLAG_MAX_BITS);
+            flags.set(TeTopology.BIT_LEARNT);
+            if (network.teTopologyId().clientId() == TeTopologyManager.DEFAULT_PROVIDER_ID) {
+                // Hard rule for now
+                flags.set(TeTopology.BIT_CUSTOMIZED);
+            }
+            CommonTopologyData common = new CommonTopologyData(network.networkId(),
+                    OptimizationType.NOT_OPTIMIZED, flags, network.ownerId());
+            intTopo.setTopologydata(common);
+            teTopologyMap.put(topoKey, intTopo);
+        }
+        // Finally Update networkMap
+        InternalNetwork newNetwork = new InternalNetwork(network);
+        newNetwork.setTeTopologyKey(topoKey);
+        networkMap.put(network.networkId(), newNetwork);
+    }
+
+    @Override
+    public void removeNetwork(KeyId networkId) {
+        // Remove it from networkMap
+        InternalNetwork network = networkMap.remove(networkId);
+        if (network != null && network.teTopologyKey() != null) {
+            removeNetworkMapEntrys(network, false);
+            teTopologyMap.remove(network.teTopologyKey());
+        }
+    }
+
+    private TeNode teNode(TeNodeKey nodeKey, InternalTeNode intNode) {
+        if (intNode == null) {
+            return null;
+        }
+        Map<Long, ConnectivityMatrix> connMatrices = null;
+        if (CollectionUtils.isNotEmpty(intNode.connMatrixKeys())) {
+            connMatrices = Maps.newHashMap();
+            for (ConnectivityMatrixKey key : intNode.connMatrixKeys()) {
+                connMatrices.put(key.entryId(), connMatrixMap.get(key));
+            }
+        }
+        List<Long> teLinkIds = null;
+        if (CollectionUtils.isNotEmpty(intNode.teLinkTpKeys())) {
+            teLinkIds = Lists.newArrayList();
+            for (TeLinkTpGlobalKey key : intNode.teLinkTpKeys()) {
+                teLinkIds = TeUtils.addListElement(teLinkIds, key.teLinkTpId());
+            }
+        }
+        List<Long> tps = null;
+        if (CollectionUtils.isNotEmpty(intNode.teTpKeys())) {
+            tps = Lists.newArrayList();
+            for (TeLinkTpGlobalKey key : intNode.teTpKeys()) {
+                tps = TeUtils.addListElement(tps, key.teLinkTpId());
+            }
+        }
+        Map<Long, TunnelTerminationPoint> ttps = null;
+        if (CollectionUtils.isNotEmpty(intNode.ttpKeys())) {
+            ttps = Maps.newHashMap();
+            for (TtpKey key : intNode.ttpKeys()) {
+                ttps.put(key.ttpId(), ttpMap.get(key));
+            }
+        }
+        return new DefaultTeNode(nodeKey.teNodeId(),
+                intNode.underlayTopologyKey(),
+                intNode.supportNodeKey(),
+                intNode.sourceTeNodeKey(),
+                intNode.teData(),
+                connMatrices, teLinkIds, ttps, tps);
+    }
+
+    @Override
+    public TeNode teNode(TeNodeKey nodeKey) {
+        InternalTeNode intNode = teNodeMap.get(nodeKey);
+        return teNode(nodeKey, intNode);
+    }
+
+    private void removeTeNodeMapEntrys(InternalTeNode intNode) {
+        // Remove connMatrixMap entries for the node
+        if (CollectionUtils.isNotEmpty(intNode.connMatrixKeys())) {
+            for (ConnectivityMatrixKey key : intNode.connMatrixKeys()) {
+                connMatrixMap.remove(key);
+            }
+        }
+        // Remove ttpMap entries for the node
+        if (CollectionUtils.isNotEmpty(intNode.ttpKeys())) {
+            for (TtpKey key : intNode.ttpKeys()) {
+                ttpMap.remove(key);
+            }
+        }
+    }
+
+    private void updateTeNode(TeNodeKey nodeKey, TeNode node, boolean parentUpdate,
+            boolean teNodeUpdate, NetworkNodeKey networkNodeKey) {
+        InternalTeTopology intTopo = teTopologyMap.get(nodeKey.teTopologyKey());
+        if (intTopo == null && !parentUpdate) {
+            log.error("TE Topology is not in dataStore for nodeUpdate {}", nodeKey);
+            return;
+        }
+        InternalTeNode curNode = teNodeMap.get(nodeKey);
+        // Update connMatrixMap
+        if (MapUtils.isNotEmpty(node.connectivityMatrices())) {
+            for (Map.Entry<Long, ConnectivityMatrix> entry : node.connectivityMatrices().entrySet()) {
+                connMatrixMap.put(new ConnectivityMatrixKey(nodeKey, entry.getKey()),
+                        entry.getValue());
+            }
+        }
+        // Update ttpMap
+        if (MapUtils.isNotEmpty(node.tunnelTerminationPoints())) {
+            for (Map.Entry<Long, TunnelTerminationPoint> entry : node.tunnelTerminationPoints().entrySet()) {
+                ttpMap.put(new TtpKey(nodeKey, entry.getKey()), entry.getValue());
+            }
+        }
+        // Update teNodeMap
+        InternalTeNode intNode = new InternalTeNode(nodeKey, node, networkNodeKey, parentUpdate);
+        teNodeMap.put(nodeKey, intNode);
+        if (curNode == null && !parentUpdate && intTopo != null) {
+            // Update InternalTeTopology
+           intTopo.setChildUpdate(true);
+           TeUtils.addListElement(intTopo.teNodeKeys(), nodeKey);
+        }
+        // Update networkNodeMap
+        if (teNodeUpdate) {
+            updateNetworkNode(networkNodeKey, networkNode(node), parentUpdate,
+                    teNodeUpdate, nodeKey);
+        }
+    }
+
+    private NetworkNode networkNode(TeNode node) {
+        KeyId nodeId = KeyId.keyId(Long.toString(node.teNodeId()));
+        List<NetworkNodeKey> supportingNodeIds = null;
+        if (node.supportingTeNodeId() != null) {
+            supportingNodeIds = Lists.newArrayList();
+            supportingNodeIds.add(new NetworkNodeKey(
+                    TeMgrUtil.toNetworkId((node.supportingTeNodeId().teTopologyKey())),
+                    KeyId.keyId(Long.toString(node.supportingTeNodeId().teNodeId()))));
+        }
+        Map<KeyId, TerminationPoint> tps = null;
+        if (node.teTerminationPointIds() != null) {
+            tps = Maps.newHashMap();
+            for (Long teTpId : node.teTerminationPointIds()) {
+                tps.put(KeyId.keyId(Long.toString(teTpId)),
+                        new DefaultTerminationPoint(KeyId.keyId(Long.toString(teTpId)),
+                                null, teTpId));
+            }
+        }
+        return new DefaultNetworkNode(nodeId, supportingNodeIds, node, tps);
+    }
+
+    @Override
+    public void updateTeNode(TeNodeKey nodeKey, TeNode node) {
+        updateTeNode(nodeKey, node, false, true, TeMgrUtil.networkNodeKey(nodeKey));
+    }
+
+    private void removeTeNode(TeNodeKey nodeKey, boolean teNodeRemove) {
+        // Remove it from InternalTeTopology first
+        InternalTeTopology intTopo = teTopologyMap.get(nodeKey.teTopologyKey());
+        if (intTopo != null && CollectionUtils.isNotEmpty(intTopo.teNodeKeys())) {
+            intTopo.setChildUpdate(true);
+            intTopo.teNodeKeys().remove(nodeKey);
+        }
+        // Then remove it from teNodeMap
+        InternalTeNode node = teNodeMap.remove(nodeKey);
+        removeTeNodeMapEntrys(node);
+        // Remove it from networkNodeMap
+        if (teNodeRemove && node != null) {
+            removeNetworkNode(node.networkNodeKey(), teNodeRemove);
+        }
+    }
+
+    @Override
+    public void removeTeNode(TeNodeKey nodeKey) {
+        removeTeNode(nodeKey, true);
+    }
+
+    private NetworkNode networkNode(NetworkNodeKey nodeKey, InternalNetworkNode intNode) {
+        if (intNode == null) {
+            return null;
+        }
+        Map<KeyId, TerminationPoint> tps = Maps.newHashMap();
+        for (KeyId tpId : intNode.tpIds()) {
+            tps.put(tpId, terminationPoint(
+                    new TerminationPointKey(nodeKey, tpId)));
+
+        }
+        return new DefaultNetworkNode(nodeKey.nodeId(), intNode.supportingNodeIds(),
+                teNode(intNode.teNodeKey()), tps);
+    }
+
+    @Override
+    public NetworkNode networkNode(NetworkNodeKey nodeKey) {
+        InternalNetworkNode intNode = networkNodeMap.get(nodeKey);
+        return networkNode(nodeKey, intNode);
+    }
+
+    private void updateNetworkNode(NetworkNodeKey nodeKey, NetworkNode node,
+            boolean parentUpdate, boolean teNodeUpdate, TeNodeKey teNodeKey) {
+        InternalNetwork intNework = null;
+        if (!parentUpdate) {
+            intNework = networkMap.get(nodeKey.networkId());
+            if (intNework == null) {
+                log.error("Network is not in dataStore for nodeUpdate {}", nodeKey);
+                return;
+            }
+        }
+
+        InternalNetworkNode exNode = networkNodeMap.get(nodeKey);
+        if (exNode != null && CollectionUtils.isNotEmpty(exNode.tpIds())) {
+            // Remove the TerminationPoints first
+            for (KeyId tpId : exNode.tpIds()) {
+                removeTerminationPoint(new TerminationPointKey(nodeKey, tpId));
+            }
+        }
+
+        if (MapUtils.isNotEmpty(node.terminationPoints())) {
+            // Update with new TerminationPoints
+            for (Map.Entry<KeyId, TerminationPoint> entry : node.terminationPoints().entrySet()) {
+                updateTerminationPoint(new TerminationPointKey(nodeKey, entry.getKey()),
+                        entry.getValue(), parentUpdate, teNodeKey);
+            }
+        }
+
+        // Update teNodeMap first
+        if (!teNodeUpdate && teNodeKey != null && node.teNode() != null) {
+            updateTeNode(teNodeKey, node.teNode(), parentUpdate, teNodeUpdate, nodeKey);
+        }
+        // Update networkNodeMap
+        InternalNetworkNode intNode = new InternalNetworkNode(node, parentUpdate);
+        intNode.setTeNodeKey(teNodeKey);
+        networkNodeMap.put(nodeKey, intNode);
+        if (exNode == null && !parentUpdate && intNework != null) {
+            // Update the InternalNetwork
+            intNework.setChildUpdate(true);
+            TeUtils.addListElement(intNework.nodeIds(), nodeKey);
+        }
+    }
+
+    @Override
+    public void updateNetworkNode(NetworkNodeKey nodeKey, NetworkNode node) {
+        TeNodeKey teNodeKey = null;
+        if (node.teNode() != null) {
+            teNodeKey = new TeNodeKey(networkMap.get(nodeKey.networkId()).teTopologyKey(),
+                                      node.teNode().teNodeId());
+        }
+        updateNetworkNode(nodeKey, node, false, false, teNodeKey);
+    }
+
+    private void removeNetworkNode(NetworkNodeKey nodeKey, boolean teNodeRemove) {
+        // Update the InternalNetwork
+        InternalNetwork intNework = networkMap.get(nodeKey.networkId());
+        if (intNework != null && CollectionUtils.isNotEmpty(intNework.nodeIds())) {
+            intNework.setChildUpdate(true);
+            intNework.nodeIds().remove(nodeKey.nodeId());
+        }
+        InternalNetworkNode intNode = networkNodeMap.remove(nodeKey);
+        if (intNode != null && CollectionUtils.isNotEmpty(intNode.tpIds())) {
+            // Remove the TerminationPoints first
+            for (KeyId tpId : intNode.tpIds()) {
+                removeTerminationPoint(new TerminationPointKey(nodeKey, tpId));
+            }
+        }
+        if (!teNodeRemove && intNode != null) {
+            // Now remove it from teNodeMap
+            removeTeNode(intNode.teNodeKey(), teNodeRemove);
+        }
+    }
+
+    @Override
+    public void removeNetworkNode(NetworkNodeKey nodeKey) {
+        removeNetworkNode(nodeKey, false);
+    }
+
+    private TeLink teLink(TeLinkTpGlobalKey linkKey, InternalTeLink intLink) {
+        if (intLink == null) {
+            return null;
+        }
+        return new DefaultTeLink(linkKey.teLinkTpKey(),
+                intLink.peerTeLinkKey(),
+                intLink.underlayTopologyKey(),
+                intLink.supportingLinkKey(),
+                intLink.sourceTeLinkKey(),
+                intLink.teData());
+    }
+
+    @Override
+    public TeLink teLink(TeLinkTpGlobalKey linkKey) {
+        InternalTeLink intLink = teLinkMap.get(linkKey);
+        return teLink(linkKey, intLink);
+    }
+
+    private void updateTeLink(TeLinkTpGlobalKey linkKey, TeLink link,
+            boolean parentUpdate, boolean teLinkUpdate, NetworkLinkKey networkLinkKey) {
+        InternalTeTopology intTopo = teTopologyMap.get(linkKey.teTopologyKey());
+        if (intTopo == null && !parentUpdate) {
+            log.error("TE Topology is not in dataStore for linkUpdate {}", linkKey);
+            return;
+        }
+        InternalTeNode intNode = teNodeMap.get(linkKey.teNodeKey());
+        if (intNode == null && !parentUpdate) {
+            log.error("TE node is not in dataStore for linkUpdate {}", linkKey);
+            return;
+        }
+        InternalTeLink exLink = teLinkMap.get(linkKey);
+
+        // Update teLinkMap
+        InternalTeLink intLink = new InternalTeLink(link, parentUpdate);
+        intLink.setNetworkLinkKey(networkLinkKey);
+        teLinkMap.put(linkKey, intLink);
+        if (exLink == null && !parentUpdate) {
+            if (intTopo != null) {
+                // Update the InternalTeTopology
+                intTopo.setChildUpdate(true);
+                intTopo.setTeLinkKeys(TeUtils.addListElement(intTopo.teLinkKeys(), linkKey));
+            }
+            if (intNode != null) {
+                // Update the InternalNode
+                intNode.setChildUpdate(true);
+                intNode.setTeLinkTpKeys(TeUtils.addListElement(intNode.teLinkTpKeys(), linkKey));
+            }
+        }
+
+        // Update networkLinkMap
+        if (teLinkUpdate) {
+            updateNetworkLink(networkLinkKey, networkLink(link), parentUpdate,
+                    teLinkUpdate, linkKey);
+        }
+    }
+
+    private NetworkLink networkLink(TeLink link) {
+        KeyId linkId = TeMgrUtil.toNetworkLinkId(link.teLinkKey());
+        NodeTpKey source = null;
+        if (link.teLinkKey() != null) {
+            source = new NodeTpKey(KeyId.keyId(Long.toString(link.teLinkKey().teNodeId())),
+                                   KeyId.keyId(Long.toString(link.teLinkKey().teLinkTpId())));
+        }
+        NodeTpKey dest = null;
+        if (link.peerTeLinkKey() != null) {
+            dest = new NodeTpKey(KeyId.keyId(Long.toString(link.peerTeLinkKey().teNodeId())),
+                    KeyId.keyId(Long.toString(link.peerTeLinkKey().teLinkTpId())));
+        }
+        List<NetworkLinkKey> supportingLinkIds = null;
+        if (link.supportingTeLinkId() != null) {
+            supportingLinkIds = Lists.newArrayList();
+            supportingLinkIds.add(new NetworkLinkKey(
+                    TeMgrUtil.toNetworkId(link.supportingTeLinkId().teTopologyKey()),
+                    TeMgrUtil.toNetworkLinkId(link.supportingTeLinkId().teLinkTpKey())));
+        }
+        return new DefaultNetworkLink(linkId, source, dest, supportingLinkIds, link);
+    }
+
+    @Override
+    public void updateTeLink(TeLinkTpGlobalKey linkKey, TeLink link) {
+        updateTeLink(linkKey, link, false, true, TeMgrUtil.networkLinkKey(linkKey));
+    }
+
+    private void removeTeLink(TeLinkTpGlobalKey linkKey, boolean teLinkRemove) {
+        // Remove it from InternalTeTopology first
+        InternalTeTopology intTopo = teTopologyMap.get(linkKey.teTopologyKey());
+        if (intTopo != null && CollectionUtils.isNotEmpty(intTopo.teLinkKeys())) {
+           intTopo.setChildUpdate(true);
+           intTopo.teLinkKeys().remove(linkKey);
+        }
+        // Remove it from InternalTeNode
+        InternalTeNode intNode = teNodeMap.get(linkKey.teNodeKey());
+        if (intNode != null && CollectionUtils.isNotEmpty(intNode.teLinkTpKeys())) {
+            intNode.setChildUpdate(true);
+            intNode.teLinkTpKeys().remove(linkKey);
+        }
+        // Then remove it from teLinkMap
+        InternalTeLink link = teLinkMap.remove(linkKey);
+        if (teLinkRemove && link != null) {
+            // Remove it from networkLinkMap
+            removeNetworkLink(link.networkLinkKey(), teLinkRemove);
+        }
+     }
+
+    @Override
+    public void removeTeLink(TeLinkTpGlobalKey linkKey) {
+        removeTeLink(linkKey, true);
+    }
+
+    private NetworkLink networkLink(NetworkLinkKey linkKey, InternalNetworkLink intLink) {
+        if (intLink == null) {
+            return null;
+        }
+        return new DefaultNetworkLink(linkKey.linkId(), intLink.source(),
+                intLink.destination(), intLink.supportingLinkIds(), teLink(intLink.teLinkKey()));
+    }
+
+    @Override
+    public NetworkLink networkLink(NetworkLinkKey linkKey) {
+        InternalNetworkLink intLink = networkLinkMap.get(linkKey);
+        return networkLink(linkKey, intLink);
+    }
+
+    private void updateNetworkLink(NetworkLinkKey linkKey, NetworkLink link,
+            boolean parentUpdate, boolean teLinkUpdate, TeLinkTpGlobalKey teLinkKey) {
+        InternalNetwork intNework = null;
+        if (!parentUpdate) {
+            intNework = networkMap.get(linkKey.networkId());
+            if (intNework == null) {
+                log.error("Network is not in dataStore for linkUpdate {}", linkKey);
+                return;
+            }
+        }
+
+        InternalNetworkLink exLink = networkLinkMap.get(linkKey);
+
+        // Now update teLinkMap first
+        if (!teLinkUpdate && teLinkKey != null) {
+            updateTeLink(teLinkKey, link.teLink(), parentUpdate, teLinkUpdate, linkKey);
+        }
+        // Update networkLinkMap
+        InternalNetworkLink intLink = new InternalNetworkLink(link, parentUpdate);
+        intLink.setTeLinkKey(teLinkKey);
+        networkLinkMap.put(linkKey, intLink);
+        if (exLink == null && !parentUpdate && intNework != null) {
+            // Update the InternalNetwork
+            intNework.setChildUpdate(true);
+            TeUtils.addListElement(intNework.linkIds(), linkKey);
+        }
+    }
+
+    @Override
+    public void updateNetworkLink(NetworkLinkKey linkKey, NetworkLink link) {
+        TeLinkTpGlobalKey teLinkKey = null;
+        if (link.teLink() != null) {
+            teLinkKey = new TeLinkTpGlobalKey(networkMap.get(linkKey.networkId()).teTopologyKey(),
+                                              link.teLink().teLinkKey());
+        }
+
+        updateNetworkLink(linkKey, link, false, false, teLinkKey);
+    }
+
+    private void removeNetworkLink(NetworkLinkKey linkKey, boolean teLinkRemove) {
+        // Update the InternalNetwork
+        InternalNetwork intNework = networkMap.get(linkKey.networkId());
+        if (intNework != null && CollectionUtils.isNotEmpty(intNework.linkIds())) {
+            intNework.setChildUpdate(true);
+            intNework.linkIds().remove(linkKey.linkId());
+        }
+        // Remove it from networkLinkMap
+        InternalNetworkLink intLink = networkLinkMap.remove(linkKey);
+        if (!teLinkRemove && intLink != null && intLink.teLinkKey() != null) {
+            // Now remove it from teLinkMap
+            removeTeLink(intLink.teLinkKey(), teLinkRemove);
+        }
+    }
+
+    @Override
+    public void removeNetworkLink(NetworkLinkKey linkKey) {
+        removeNetworkLink(linkKey, false);
+    }
+
+    private TerminationPoint terminationPoint(TerminationPointKey tpKey) {
+        InternalTerminationPoint intTp = tpMap.get(tpKey);
+        if (intTp == null) {
+            return null;
+        }
+        return new DefaultTerminationPoint(tpKey.tpId(), intTp.supportingTpIds(),
+                intTp.teTpKey().teLinkTpId());
+    }
+
+    private void updateTerminationPoint(TerminationPointKey tpKey,
+            TerminationPoint tp, boolean parentUpdate, TeNodeKey teNodeKey) {
+        TeNodeKey myTeNodeKey;
+        InternalNetworkNode intNode = null;
+        if (!parentUpdate) {
+            intNode = networkNodeMap.get(tpKey.nodeId());
+            if (intNode == null) {
+                log.error(" node is not in dataStore for tp update {}", tpKey);
+                return;
+            }
+            myTeNodeKey = intNode.teNodeKey();
+        } else {
+            myTeNodeKey = teNodeKey;
+        }
+        TeLinkTpGlobalKey teTpKey = new TeLinkTpGlobalKey(myTeNodeKey, tp.teTpId());
+
+        boolean newTp = tpMap.get(tpKey) == null;
+        InternalTerminationPoint intTp = new InternalTerminationPoint(tp);
+        intTp.setTeTpKey(teTpKey);
+        tpMap.put(tpKey, intTp);
+        if (newTp) {
+            // Update tpKeyMap
+            tpKeyMap.put(teTpKey, tpKey);
+            if (!parentUpdate && intNode != null) {
+                // Update InternalNetworkNode
+                intNode.setChildUpdate(true);
+                intNode.setTpIds(TeUtils.addListElement(intNode.tpIds(), tpKey.tpId()));
+            }
+        }
+    }
+
+    @Override
+    public void updateTerminationPoint(TerminationPointKey tpKey,
+            TerminationPoint tp) {
+        updateTerminationPoint(tpKey, tp, false, null);
+    }
+
+    @Override
+    public void removeTerminationPoint(TerminationPointKey tpKey) {
+        // Update InternalNetworkNode
+        InternalNetworkNode intNode = networkNodeMap.get(tpKey.nodeId());
+        if (intNode != null && CollectionUtils.isNotEmpty(intNode.tpIds())) {
+            intNode.setChildUpdate(true);
+            intNode.tpIds().remove(tpKey.tpId());
+        }
+        // Remove it from tpMap
+        InternalTerminationPoint tp = tpMap.remove(tpKey);
+        // Remove it from tpKeyMap
+        if (tp != null) {
+            tpKeyMap.remove(tp.teTpKey());
+        }
+    }
+
+    @Override
+    public TunnelTerminationPoint tunnelTerminationPoint(TtpKey ttpId) {
+        return ttpMap.get(ttpId);
+    }
+
+    @Override
+    public long nextTeTopologyId() {
+        return nextTeTopologyId.getAndIncrement();
+    }
+
+    @Override
+    public long nextTeNodeId(TeTopologyKey topoKey) {
+        return teTopologyMap.get(topoKey).nextTeNodeId();
+    }
+
+    @Override
+    public void setNextTeNodeId(TeTopologyKey topoKey, long nextNodeId) {
+        teTopologyMap.get(topoKey).setNextTeNodeId(nextNodeId);
+    }
+
+    @Override
+    public KeyId networkId(TeTopologyKey teTopologyKey) {
+        return teTopologyMap.get(teTopologyKey).topologyData().networkId();
+    }
+
+    @Override
+    public NetworkNodeKey nodeKey(TeNodeKey teNodeKey) {
+        return teNodeMap.get(teNodeKey).networkNodeKey();
+    }
+
+    @Override
+    public NetworkLinkKey linkKey(TeLinkTpGlobalKey teLinkKey) {
+        return teLinkMap.get(teLinkKey).networkLinkKey();
+    }
+
+    @Override
+    public TerminationPointKey terminationPointKey(TeLinkTpGlobalKey teTpKey) {
+        return tpKeyMap.get(teTpKey);
+    }
+
+    @Override
+    public void setMapEventQueue(BlockingQueue<TeTopologyMapEvent> queue) {
+        mapEventQueue = queue;
+    }
+}
+
