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;
+    }
+}
+
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalNetwork.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalNetwork.java
new file mode 100644
index 0000000..5aea01e
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalNetwork.java
@@ -0,0 +1,214 @@
+/*
+ * 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 java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.MapUtils;
+import org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.Network;
+import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetopology.management.api.link.NetworkLink;
+import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
+import org.onosproject.tetopology.management.api.node.NetworkNode;
+import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+/**
+ * Network representation in store.
+ */
+public class InternalNetwork {
+    private TeTopologyKey teTopologyKey;
+    private List<KeyId> supportingNetworkIds;
+    private boolean serverProvided;
+    private List<NetworkNodeKey> nodeIds;
+    private List<NetworkLinkKey> linkIds;
+    private boolean childUpdate = false;
+
+    /**
+     * Creates an instance of InternalNetwork.
+     *
+     * @param network the Network object
+     */
+    public InternalNetwork(Network network) {
+        this.supportingNetworkIds = network
+                .supportingNetworkIds() == null ? null
+                                                : Lists.newArrayList(network
+                                                        .supportingNetworkIds());
+        this.serverProvided = network.isServerProvided();
+        // NetworkNodeKey
+        if (MapUtils.isNotEmpty(network.nodes())) {
+            this.nodeIds = Lists.newArrayList();
+            for (Map.Entry<KeyId, NetworkNode> entry : network.nodes().entrySet()) {
+                this.nodeIds.add(new NetworkNodeKey(network.networkId(), entry.getKey()));
+            }
+        }
+        // NetworkLinkKey
+        if (MapUtils.isNotEmpty(network.links())) {
+            this.linkIds = Lists.newArrayList();
+            for (Map.Entry<KeyId, NetworkLink> entry : network.links().entrySet()) {
+                this.linkIds.add(new NetworkLinkKey(network.networkId(), entry.getKey()));
+            }
+        }
+    }
+
+    /**
+     * Creates a default instance of InternalNetwork.
+     */
+    public InternalNetwork() {
+    }
+
+    /**
+     * Returns the supporting network Ids.
+     *
+     * @return the supportingNetworkIds
+     */
+    public List<KeyId> supportingNetworkIds() {
+        if (supportingNetworkIds == null) {
+            return null;
+        }
+        return ImmutableList.copyOf(supportingNetworkIds);
+    }
+
+    /**
+     * Returns if the network topology is provided by a server or is
+     * configured by a client.
+     *
+     * @return true if the network is provided by a server; false otherwise
+     */
+    public boolean serverProvided() {
+        return serverProvided;
+    }
+
+    /**
+     * @param serverProvided the serverProvided to set
+     */
+    public void setServerProvided(boolean serverProvided) {
+        this.serverProvided = serverProvided;
+    }
+
+    /**
+     * Returns the list of node Ids in the network.
+     *
+     * @return the nodeIds
+     */
+    public List<NetworkNodeKey> nodeIds() {
+        return nodeIds;
+    }
+
+    /**
+     * Returns the TE topology key for the network.
+     *
+     * @return the teTopologyKey
+     */
+    public TeTopologyKey teTopologyKey() {
+        return teTopologyKey;
+    }
+
+    /**
+     * Sets the TE topology key for the network.
+     *
+     * @param teTopologyKey the teTopologyKey to set
+     */
+    public void setTeTopologyKey(TeTopologyKey teTopologyKey) {
+        this.teTopologyKey = teTopologyKey;
+    }
+
+    /**
+     * Set the list of node Ids in the network.
+     *
+     * @param nodeIds the nodeIds to set
+     */
+    public void setNodeIds(List<NetworkNodeKey> nodeIds) {
+        this.nodeIds = nodeIds;
+    }
+
+    /**
+     * Returns the list of link Ids in the network.
+     *
+     * @return the linkIds
+     */
+    public List<NetworkLinkKey> linkIds() {
+        return linkIds;
+    }
+
+    /**
+     * Set the list of link Ids in the network.
+     *
+     * @param linkIds the linkIds to set
+     */
+    public void setLinkIds(List<NetworkLinkKey> linkIds) {
+        this.linkIds = linkIds;
+    }
+
+    /**
+     * Returns the flag if the data was updated by child change.
+     *
+     * @return value of childUpdate
+     */
+    public boolean childUpdate() {
+        return childUpdate;
+    }
+
+    /**
+     * Sets the flag if the data was updated by child change.
+     *
+     * @param childUpdate the childUpdate value to set
+     */
+    public void setChildUpdate(boolean childUpdate) {
+        this.childUpdate = childUpdate;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(teTopologyKey, nodeIds, linkIds,
+                supportingNetworkIds, serverProvided);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof InternalNetwork) {
+            InternalNetwork that = (InternalNetwork) object;
+            return Objects.equal(this.teTopologyKey, that.teTopologyKey) &&
+                    Objects.equal(this.nodeIds, that.nodeIds) &&
+                    Objects.equal(this.linkIds, that.linkIds) &&
+                    Objects.equal(this.supportingNetworkIds, that.supportingNetworkIds) &&
+                    Objects.equal(this.serverProvided, that.serverProvided);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("teTopologyKey", teTopologyKey)
+                .add("nodeIds", nodeIds)
+                .add("linkIds", linkIds)
+                .add("supportingNetworkIds", supportingNetworkIds)
+                .add("serverProvided", serverProvided)
+                .add("childUpdate", childUpdate)
+                .toString();
+    }
+
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalNetworkLink.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalNetworkLink.java
new file mode 100644
index 0000000..e1f1fba
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalNetworkLink.java
@@ -0,0 +1,141 @@
+/*
+ * 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 java.util.List;
+
+import org.onosproject.tetopology.management.api.link.NetworkLink;
+import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
+import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
+import org.onosproject.tetopology.management.api.node.NodeTpKey;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+/**
+ * Network Link representation in store.
+ */
+public class InternalNetworkLink {
+    private NodeTpKey source;
+    private NodeTpKey destination;
+    private List<NetworkLinkKey> supportingLinkIds;
+    private TeLinkTpGlobalKey teLinkKey;
+    private boolean parentUpdate;
+
+    /**
+     * Creates an instance of InternalNetworkLink.
+     *
+     * @param link the network link
+     * @param parentUpdate the flag if the data is updated by parent
+     */
+    public InternalNetworkLink(NetworkLink link,  boolean parentUpdate) {
+        source = link.source();
+        destination = link.destination();
+        supportingLinkIds = link
+                .supportingLinkIds() == null ? null
+                                             : Lists.newArrayList(link
+                                                     .supportingLinkIds());
+        this.parentUpdate = parentUpdate;
+    }
+
+    /**
+     * Returns the link source termination point.
+     *
+     * @return source link termination point id
+     */
+    public NodeTpKey source() {
+        return source;
+    }
+
+    /**
+     * Returns the link destination termination point.
+     *
+     * @return destination link termination point id
+     */
+    public NodeTpKey destination() {
+        return destination;
+    }
+
+    /**
+     * Returns the supporting link ids.
+     *
+     * @return list of the ids of the supporting links
+     */
+    public List<NetworkLinkKey> supportingLinkIds() {
+        return supportingLinkIds == null ? null
+                                         : ImmutableList
+                                                 .copyOf(supportingLinkIds);
+    }
+
+    /**
+     * Returns the TE link key.
+     *
+     * @return the teLinkKey
+     */
+    public TeLinkTpGlobalKey teLinkKey() {
+        return teLinkKey;
+    }
+
+    /**
+     * Sets the TE link key.
+     *
+     * @param teLinkKey the teLinkKey to set
+     */
+    public void setTeLinkKey(TeLinkTpGlobalKey teLinkKey) {
+        this.teLinkKey = teLinkKey;
+    }
+
+    /**
+     * Returns the flag if the data was updated by parent change.
+     *
+     * @return value of parentUpdate
+     */
+    public boolean parentUpdate() {
+        return parentUpdate;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(source, destination, supportingLinkIds, teLinkKey);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof InternalNetworkLink) {
+            InternalNetworkLink that = (InternalNetworkLink) object;
+            return Objects.equal(source, that.source)
+                    && Objects.equal(destination, that.destination)
+                    && Objects.equal(supportingLinkIds, that.supportingLinkIds)
+                    && Objects.equal(teLinkKey, that.teLinkKey);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("source", source)
+                .add("destination", destination)
+                .add("supportingLinkIds", supportingLinkIds)
+                .add("teLinkKey", teLinkKey)
+                .toString();
+    }
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalNetworkNode.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalNetworkNode.java
new file mode 100644
index 0000000..72b2e3c
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalNetworkNode.java
@@ -0,0 +1,177 @@
+/*
+ * 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 java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.MapUtils;
+import org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.node.NetworkNode;
+import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+import org.onosproject.tetopology.management.api.node.TerminationPoint;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+/**
+ * Network Node representation in store.
+ */
+public class InternalNetworkNode {
+    private List<NetworkNodeKey> supportingNodeIds;
+    private List<KeyId> tpIds;
+    private TeNodeKey teNodeKey;
+    private boolean parentUpdate;
+    private boolean childUpdate;
+
+    /**
+     * Creates an instance of InternalNetworkNode.
+     *
+     * @param node the network node
+     * @param parentUpdate the flag if the data is updated by parent
+     */
+    public InternalNetworkNode(NetworkNode node,  boolean parentUpdate) {
+        supportingNodeIds = node
+                .supportingNodeIds() == null ? null
+                                             : Lists.newArrayList(node
+                                                     .supportingNodeIds());
+        if (MapUtils.isNotEmpty(node.terminationPoints())) {
+            tpIds = Lists.newArrayList();
+            for (Map.Entry<KeyId, TerminationPoint> entry : node
+                    .terminationPoints().entrySet()) {
+                tpIds.add(entry.getKey());
+            }
+        }
+        this.parentUpdate = parentUpdate;
+    }
+
+    /**
+     * Returns the list of supporting node Ids.
+     *
+     * @return the supporting nodeIds
+     */
+    public List<NetworkNodeKey> supportingNodeIds() {
+        return supportingNodeIds == null ? null
+                                         : ImmutableList
+                                                 .copyOf(supportingNodeIds);
+    }
+
+    /**
+     * Sets the list of supporting node Ids.
+     *
+     * @param supportingNodeIds the supportingNodeIds to set
+     */
+    public void setSupportingNodeIds(List<NetworkNodeKey> supportingNodeIds) {
+        this.supportingNodeIds = supportingNodeIds == null ? null
+                                                           : Lists.newArrayList(supportingNodeIds);
+    }
+
+    /**
+     * Returns the list of termination point Ids.
+     *
+     * @return the termination point Ids
+     */
+    public List<KeyId> tpIds() {
+        return tpIds;
+    }
+
+    /**
+     * Sets the list of termination point Ids.
+     *
+     * @param tpIds the tpIds to set
+     */
+    public void setTpIds(List<KeyId> tpIds) {
+        this.tpIds = tpIds;
+    }
+
+    /**
+     * Returns the TE Node key.
+     *
+     * @return the teNodeKey
+     */
+    public TeNodeKey teNodeKey() {
+        return teNodeKey;
+    }
+
+    /**
+     * Sets the TE Node key.
+     *
+     * @param teNodeKey the teNodeKey to set
+     */
+    public void setTeNodeKey(TeNodeKey teNodeKey) {
+        this.teNodeKey = teNodeKey;
+    }
+
+    /**
+     * Returns the flag if the data was updated by parent change.
+     *
+     * @return value of parentUpdate
+     */
+    public boolean parentUpdate() {
+        return parentUpdate;
+    }
+
+    /**
+     * Returns the flag if the data was updated by child change.
+     *
+     * @return value of childUpdate
+     */
+    public boolean childUpdate() {
+        return childUpdate;
+    }
+
+    /**
+     * Sets the flag if the data was updated by child change.
+     *
+     * @param childUpdate the childUpdate value to set
+     */
+    public void setChildUpdate(boolean childUpdate) {
+        this.childUpdate = childUpdate;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(supportingNodeIds, tpIds, teNodeKey);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof InternalNetworkNode) {
+            InternalNetworkNode that = (InternalNetworkNode) object;
+            return Objects.equal(supportingNodeIds, that.supportingNodeIds)
+                    && Objects.equal(tpIds, that.tpIds)
+                    && Objects.equal(teNodeKey, that.teNodeKey);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("supportingNodeIds", supportingNodeIds)
+                .add("tpIds", tpIds)
+                .add("teNodeKey", teNodeKey)
+                .add("parentUpdate", parentUpdate)
+                .add("childUpdate", childUpdate)
+                .toString();
+    }
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTeLink.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTeLink.java
new file mode 100644
index 0000000..6274a4b
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTeLink.java
@@ -0,0 +1,213 @@
+/*
+ * 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 org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetopology.management.api.link.CommonLinkData;
+import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
+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 com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+
+/**
+ * The TE link representation in store.
+ */
+public class InternalTeLink {
+    private TeLinkTpKey peerTeLinkKey;
+    private TeTopologyKey underlayTopologyKey;
+    private TeLinkTpGlobalKey supportingLinkKey;
+    private TeLinkTpGlobalKey sourceTeLinkKey;
+    private CommonLinkData teData;
+    private NetworkLinkKey networkLinkKey;
+    private boolean parentUpdate;
+
+    /**
+     * Creates an instance of InternalLink.
+     *
+     * @param link the TE link
+     * @param parentUpdate indicator the TE node is updated by parent
+     */
+    public InternalTeLink(TeLink link, boolean parentUpdate) {
+        this.parentUpdate = parentUpdate;
+        // Peer link key
+        this.peerTeLinkKey = link.peerTeLinkKey();
+        // Underlay topology
+        this.underlayTopologyKey = link.underlayTeTopologyId();
+        // Supporting topology
+        this.supportingLinkKey = link.supportingTeLinkId();
+        // Source topology
+        this.sourceTeLinkKey = link.sourceTeLinkId();
+        // Common data
+        this.teData = new CommonLinkData(link);
+    }
+
+    /**
+     * Returns the bi-directional peer link key.
+     *
+     * @return the peerTeLinkKey
+     */
+    public TeLinkTpKey peerTeLinkKey() {
+        return peerTeLinkKey;
+    }
+
+    /**
+     * Sets the bi-directional peer link key.
+     *
+     * @param peerTeLinkKey the peerTeLinkKey to set
+     */
+    public void setPeerTeLinkKey(TeLinkTpKey peerTeLinkKey) {
+        this.peerTeLinkKey = peerTeLinkKey;
+    }
+
+    /**
+     * Returns the link underlay topology key.
+     *
+     * @return the underlayTopologyKey
+     */
+    public TeTopologyKey underlayTopologyKey() {
+        return underlayTopologyKey;
+    }
+
+    /**
+     * Sets the link underlay topology key.
+     *
+     * @param underlayTopologyKey the underlayTopologyKey to set
+     */
+    public void setUnderlayTopologyKey(TeTopologyKey underlayTopologyKey) {
+        this.underlayTopologyKey = underlayTopologyKey;
+    }
+
+    /**
+     * Returns the supporting link key.
+     *
+     * @return the supportingLinkKey
+     */
+    public TeLinkTpGlobalKey supportingLinkKey() {
+        return supportingLinkKey;
+    }
+
+    /**
+     * Sets the supporting link key.
+     *
+     * @param supportingLinkKey the supportingLinkKey to set
+     */
+    public void setSupportingLinkKey(TeLinkTpGlobalKey supportingLinkKey) {
+        this.supportingLinkKey = supportingLinkKey;
+    }
+
+    /**
+     * Returns the source link key.
+     *
+     * @return the sourceTeLinkKey
+     */
+    public TeLinkTpGlobalKey sourceTeLinkKey() {
+        return sourceTeLinkKey;
+    }
+
+    /**
+     * Sets the source link key.
+     *
+     * @param sourceTeLinkKey the sourceTeLinkKey to set
+     */
+    public void setSourceTeNodeKey(TeLinkTpGlobalKey sourceTeLinkKey) {
+        this.sourceTeLinkKey = sourceTeLinkKey;
+    }
+
+    /**
+     * Returns the link common data.
+     *
+     * @return the teData
+     */
+    public CommonLinkData teData() {
+        return teData;
+    }
+
+    /**
+     * Sets the link common data.
+     *
+     * @param teData the teData to set
+     */
+    public void setTeData(CommonLinkData teData) {
+        this.teData = teData;
+    }
+
+    /**
+     * Sets the network link key.
+     *
+     * @param networkLinkKey the networkLinkKey to set
+     */
+    public void setNetworkLinkKey(NetworkLinkKey networkLinkKey) {
+        this.networkLinkKey = networkLinkKey;
+    }
+
+    /**
+     * Returns the network link key.
+     *
+     * @return the networkLinkKey
+     */
+    public NetworkLinkKey networkLinkKey() {
+        return networkLinkKey;
+    }
+
+    /**
+     * Returns the indicator if the data was updated by parent.
+     *
+     * @return value of parentUpdate
+     */
+    public boolean parentUpdate() {
+        return parentUpdate;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(peerTeLinkKey, underlayTopologyKey,
+                supportingLinkKey, sourceTeLinkKey, teData, networkLinkKey);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof InternalTeLink) {
+            InternalTeLink that = (InternalTeLink) object;
+            return Objects.equal(peerTeLinkKey, that.peerTeLinkKey)
+                    && Objects.equal(underlayTopologyKey,
+                                     that.underlayTopologyKey)
+                    && Objects.equal(supportingLinkKey, that.supportingLinkKey)
+                    && Objects.equal(sourceTeLinkKey, that.sourceTeLinkKey)
+                    && Objects.equal(networkLinkKey, that.networkLinkKey)
+                    && Objects.equal(teData, that.teData);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("peerTeLinkKey", peerTeLinkKey)
+                .add("underlayTopologyKey", underlayTopologyKey)
+                .add("supportingLinkKey", supportingLinkKey)
+                .add("sourceTeLinkKey", sourceTeLinkKey)
+                .add("teData", teData)
+                .add("networkLinkKey", networkLinkKey)
+                .add("parentUpdate", parentUpdate)
+                .toString();
+    }
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTeNode.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTeNode.java
new file mode 100644
index 0000000..03d47ff
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTeNode.java
@@ -0,0 +1,348 @@
+/*
+ * 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 java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
+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.NetworkNodeKey;
+import org.onosproject.tetopology.management.api.node.TeNode;
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+import org.onosproject.tetopology.management.api.node.TtpKey;
+import org.onosproject.tetopology.management.api.node.TunnelTerminationPoint;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.Lists;
+
+/**
+ * The Node representation in store.
+ */
+public class InternalTeNode {
+    private CommonNodeData teData;
+    private TeTopologyKey underlayTopologyKey;
+    private TeNodeKey supportNodeKey;
+    private TeNodeKey sourceTeNodeKey;
+    private List<ConnectivityMatrixKey> connMatrixKeys;
+    private List<TeLinkTpGlobalKey> teLinkTpKeys;
+    private List<TeLinkTpGlobalKey> teTpKeys;
+    private List<TtpKey> ttpKeys;
+    private NetworkNodeKey networkNodeKey;
+    private boolean parentUpdate;
+    private boolean childUpdate;
+
+    // Next available TE link Id egressing from the TE node.
+    private long nextTeLinkId;
+
+    /**
+     * Creates an instance of InternalTeNode.
+     *
+     * @param nodeKey the TE node key
+     * @param node the TE node
+     * @param networkNodeKey the network node key
+     * @param parentUpdate the flag if the data is updated by parent
+     */
+    public InternalTeNode(TeNodeKey nodeKey, TeNode node,
+           NetworkNodeKey networkNodeKey, boolean parentUpdate) {
+        this.networkNodeKey = networkNodeKey;
+        this.parentUpdate = parentUpdate;
+        // Underlay topology
+        this.underlayTopologyKey = node.underlayTeTopologyId();
+        // Supporting topology
+        this.supportNodeKey = node.supportingTeNodeId();
+        // Source topology
+        this.sourceTeNodeKey = node.sourceTeNodeId();
+        // Common data
+        this.teData = new CommonNodeData(node);
+        // Connectivity matrix
+        if (MapUtils.isNotEmpty(node.connectivityMatrices())) {
+            this.connMatrixKeys = Lists.newArrayList();
+            for (Map.Entry<Long, ConnectivityMatrix> entry : node.connectivityMatrices().entrySet()) {
+                this.connMatrixKeys.add(new ConnectivityMatrixKey(nodeKey, entry.getKey()));
+            }
+        }
+        // Tunnel termination point
+        if (MapUtils.isNotEmpty(node.tunnelTerminationPoints())) {
+            this.ttpKeys = Lists.newArrayList();
+            for (Map.Entry<Long, TunnelTerminationPoint> entry : node.tunnelTerminationPoints().entrySet()) {
+                this.ttpKeys.add(new TtpKey(nodeKey, entry.getKey()));
+            }
+        }
+        // teLink Keys
+        if (CollectionUtils.isNotEmpty(node.teLinkIds())) {
+            this.teLinkTpKeys = Lists.newArrayList();
+            for (Long linkId : node.teLinkIds()) {
+                this.teLinkTpKeys.add(new TeLinkTpGlobalKey(nodeKey, linkId));
+            }
+
+        }
+        // teTp Keys
+        if (CollectionUtils.isNotEmpty(node.teTerminationPointIds())) {
+            this.teTpKeys = Lists.newArrayList();
+            for (Long tpId : node.teTerminationPointIds()) {
+                this.teTpKeys.add(new TeLinkTpGlobalKey(nodeKey, tpId));
+            }
+        }
+    }
+
+    /**
+     * Returns the node common data.
+     *
+     * @return the teData
+     */
+    public CommonNodeData teData() {
+        return teData;
+    }
+
+    /**
+     * Sets the node common data.
+     *
+     * @param teData the teData to set
+     */
+    public void setTeData(CommonNodeData teData) {
+        this.teData = teData;
+    }
+
+    /**
+     * Returns the node underlay topology key.
+     *
+     * @return the underlayTopologyKey
+     */
+    public TeTopologyKey underlayTopologyKey() {
+        return underlayTopologyKey;
+    }
+
+    /**
+     * Sets the node underlay topology key.
+     *
+     * @param underlayTopologyKey the underlayTopologyKey to set
+     */
+    public void setUnderlayTopologyKey(TeTopologyKey underlayTopologyKey) {
+        this.underlayTopologyKey = underlayTopologyKey;
+    }
+
+    /**
+     * Returns the supporting node key.
+     *
+     * @return the supportNodeKey
+     */
+    public TeNodeKey supportNodeKey() {
+        return supportNodeKey;
+    }
+
+    /**
+     * Sets the supporting node key.
+     *
+     * @param supportNodeKey the supportNodeKey to set
+     */
+    public void setSupportNodeKey(TeNodeKey supportNodeKey) {
+        this.supportNodeKey = supportNodeKey;
+    }
+
+    /**
+     * Returns the source node key.
+     *
+     * @return the sourceTeNodeKey
+     */
+    public TeNodeKey sourceTeNodeKey() {
+        return sourceTeNodeKey;
+    }
+
+    /**
+     * Sets the source node key.
+     *
+     * @param sourceTeNodeKey the sourceTeNodeKey to set
+     */
+    public void setSourceTeNodeKey(TeNodeKey sourceTeNodeKey) {
+        this.sourceTeNodeKey = sourceTeNodeKey;
+    }
+
+    /**
+     * Returns the node connect matrix keys.
+     *
+     * @return the connMatrixKeys
+     */
+    public List<ConnectivityMatrixKey> connMatrixKeys() {
+        return connMatrixKeys;
+    }
+
+    /**
+     * Sets the node connect matrix keys.
+     *
+     * @param connMatrixKeys the connMatrixKeys to set
+     */
+    public void setConnMatrixKeys(List<ConnectivityMatrixKey> connMatrixKeys) {
+        this.connMatrixKeys = connMatrixKeys;
+    }
+
+    /**
+     * Returns the TE link Ids.
+     *
+     * @return the teLinkTpKeys
+     */
+    public List<TeLinkTpGlobalKey> teLinkTpKeys() {
+        return teLinkTpKeys;
+    }
+
+    /**
+     * Sets the TE link Ids from the node.
+     *
+     * @param teLinkTpKeys the teLinkTpKeys to set
+     */
+    public void setTeLinkTpKeys(List<TeLinkTpGlobalKey> teLinkTpKeys) {
+        this.teLinkTpKeys = teLinkTpKeys;
+    }
+
+    /**
+     * Returns the TE termitation point Ids.
+     *
+     * @return the teTpKeys
+     */
+    public List<TeLinkTpGlobalKey> teTpKeys() {
+        return teTpKeys;
+    }
+
+    /**
+     * Sets the TE termitation point Ids.
+     *
+     * @param teTpKeys the teTpKeys to set
+     */
+    public void setTeTpKeys(List<TeLinkTpGlobalKey> teTpKeys) {
+        this.teTpKeys = teTpKeys;
+    }
+
+    /**
+     * Returns the list of Tunnel Termination Point keys of the node.
+     *
+     * @return the ttpKeys
+     */
+    public List<TtpKey> ttpKeys() {
+        return ttpKeys;
+    }
+
+    /**
+     * Sets the list of Tunnel Termination Point keys.
+     *
+     * @param ttpKeys the ttpKeys to set
+     */
+    public void setTtpKeys(List<TtpKey> ttpKeys) {
+        this.ttpKeys = ttpKeys;
+    }
+
+    /**
+     * Returns the network node Key.
+     *
+     * @return the networkNodeKey
+     */
+    public NetworkNodeKey networkNodeKey() {
+        return networkNodeKey;
+    }
+
+    /**
+     * Returns the next available TE link id from the node.
+     *
+     * @return the nextTeLinkId
+     */
+    public long nextTeLinkId() {
+        return nextTeLinkId;
+    }
+
+    /**
+     * Sets the next available TE link id.
+     *
+     * @param nextTeLinkId the nextTeLinkId to set
+     */
+    public void setNextTeLinkId(long nextTeLinkId) {
+        this.nextTeLinkId = nextTeLinkId;
+    }
+
+    /**
+     * Returns the flag if the data was updated by parent change.
+     *
+     * @return value of parentUpdate
+     */
+    public boolean parentUpdate() {
+        return parentUpdate;
+    }
+
+    /**
+     * Returns the flag if the data was updated by child change.
+     *
+     * @return value of childUpdate
+     */
+    public boolean childUpdate() {
+        return childUpdate;
+    }
+
+    /**
+     * Sets the flag if the data was updated by child change.
+     *
+     * @param childUpdate the childUpdate value to set
+     */
+    public void setChildUpdate(boolean childUpdate) {
+        this.childUpdate = childUpdate;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(teData, underlayTopologyKey, supportNodeKey,
+                sourceTeNodeKey, connMatrixKeys, teLinkTpKeys, ttpKeys, networkNodeKey);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof InternalTeNode) {
+            InternalTeNode that = (InternalTeNode) object;
+            return Objects.equal(teData, that.teData)
+                    && Objects.equal(underlayTopologyKey,
+                                     that.underlayTopologyKey)
+                    && Objects.equal(supportNodeKey, that.supportNodeKey)
+                    && Objects.equal(sourceTeNodeKey, that.sourceTeNodeKey)
+                    && Objects.equal(connMatrixKeys, that.connMatrixKeys)
+                    && Objects.equal(teLinkTpKeys, that.teLinkTpKeys)
+                    && Objects.equal(ttpKeys, that.ttpKeys)
+                    && Objects.equal(networkNodeKey, that.networkNodeKey);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("teData", teData)
+                .add("underlayTopologyKey", underlayTopologyKey)
+                .add("supportNodeKey", supportNodeKey)
+                .add("sourceTeNodeKey", sourceTeNodeKey)
+                .add("connMatrixKeys", connMatrixKeys)
+                .add("teLinkTpKeys", teLinkTpKeys)
+                .add("ttpKeys", ttpKeys)
+                .add("nextTeLinkId", nextTeLinkId)
+                .add("networkNodeKey", networkNodeKey)
+                .add("parentUpdate", parentUpdate)
+                .add("childUpdate", childUpdate)
+                .toString();
+    }
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTeTopology.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTeTopology.java
new file mode 100644
index 0000000..ed71d47
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTeTopology.java
@@ -0,0 +1,211 @@
+/*
+ * 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.TeConstants.NIL_LONG_VALUE;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.MapUtils;
+import org.onosproject.tetopology.management.api.CommonTopologyData;
+import org.onosproject.tetopology.management.api.TeTopology;
+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.node.TeNode;
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.Lists;
+
+/**
+ * TE topology representation in store.
+ */
+public class InternalTeTopology {
+    private String teTopologyId;
+    private List<TeNodeKey> teNodeKeys;
+    private List<TeLinkTpGlobalKey> teLinkKeys;
+    private CommonTopologyData topologyData;
+    private long nextTeNodeId = NIL_LONG_VALUE;
+    private boolean childUpdate;
+
+    /**
+     * Creates an instance of InternalTeTopology.
+     *
+     * @param teTopology the TE Topology object
+     */
+    public InternalTeTopology(TeTopology teTopology) {
+        this.teTopologyId = teTopology.teTopologyIdStringValue();
+        this.topologyData = new CommonTopologyData(teTopology);
+        // teNodeKeys
+        if (MapUtils.isNotEmpty(teTopology.teNodes())) {
+            this.teNodeKeys = Lists.newArrayList();
+            for (Map.Entry<Long, TeNode> entry : teTopology.teNodes().entrySet()) {
+                this.teNodeKeys.add(new TeNodeKey(teTopology.teTopologyId(), entry.getKey()));
+            }
+        }
+        // teLink Keys
+        if (MapUtils.isNotEmpty(teTopology.teLinks())) {
+            this.teLinkKeys = Lists.newArrayList();
+            for (Map.Entry<TeLinkTpKey, TeLink> entry : teTopology.teLinks().entrySet()) {
+                this.teLinkKeys.add(new TeLinkTpGlobalKey(teTopology.teTopologyId(), entry.getKey()));
+            }
+        }
+    }
+
+    /**
+     * Creates a default instance of InternalNetwork.
+     *
+     * @param teTopologyId string value of id
+     */
+    public InternalTeTopology(String teTopologyId) {
+        this.teTopologyId = teTopologyId;
+    }
+
+    /**
+     * Returns the TE Topology Id string value.
+     *
+     * @return the teTopologyId
+     */
+    public String teTopologyId() {
+        return teTopologyId;
+    }
+
+    /**
+     * Returns the list of TE node keys in the topology.
+     *
+     * @return the teNodeKeys
+     */
+    public List<TeNodeKey> teNodeKeys() {
+        return teNodeKeys;
+    }
+
+    /**
+     * Sets the list of TE node keys.
+     *
+     * @param teNodeKeys the teNodeKeys to set
+     */
+    public void setTeNodeKeys(List<TeNodeKey> teNodeKeys) {
+        this.teNodeKeys = teNodeKeys;
+    }
+
+    /**
+     * Returns the list of TE link keys in the topology.
+     *
+     * @return the teLinkKeys
+     */
+    public List<TeLinkTpGlobalKey> teLinkKeys() {
+        return teLinkKeys;
+    }
+
+    /**
+     * Sets the list of TE link keys.
+     *
+     * @param teLinkKeys the teLinkKeys to set
+     */
+    public void setTeLinkKeys(List<TeLinkTpGlobalKey> teLinkKeys) {
+        this.teLinkKeys = teLinkKeys;
+    }
+
+    /**
+     * Returns the common TE topology data.
+     *
+     * @return the topology data
+     */
+    public CommonTopologyData topologyData() {
+        return topologyData;
+    }
+
+    /**
+     * Sets the common TE topology data.
+     *
+     * @param topologyData the topologyData to set
+     */
+    public void setTopologydata(CommonTopologyData topologyData) {
+        this.topologyData = topologyData;
+    }
+
+    /**
+     * Returns the next available TE node Id.
+     *
+     * @return the next TE nodeId
+     */
+    public long nextTeNodeId() {
+        return nextTeNodeId;
+    }
+
+    /**
+     * Sets the next available TE node Id.
+     *
+     * @param nextTeNodeId the nextTeNodeId to set
+     */
+    public void setNextTeNodeId(long nextTeNodeId) {
+        this.nextTeNodeId = nextTeNodeId;
+    }
+
+    /**
+     * Returns the flag if the data was updated by child change.
+     *
+     * @return value of childUpdate
+     */
+    public boolean childUpdate() {
+        return childUpdate;
+    }
+
+    /**
+     * Sets the flag if the data was updated by child change.
+     *
+     * @param childUpdate the childUpdate value to set
+     */
+    public void setChildUpdate(boolean childUpdate) {
+        this.childUpdate = childUpdate;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(teTopologyId, teNodeKeys, teLinkKeys,
+                topologyData);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof InternalTeTopology) {
+            InternalTeTopology that = (InternalTeTopology) object;
+            return Objects.equal(teTopologyId, that.teTopologyId)
+                    && Objects.equal(teNodeKeys, that.teNodeKeys)
+                    && Objects.equal(teLinkKeys, that.teLinkKeys)
+                    && Objects.equal(topologyData, that.topologyData);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("teTopologyId", teTopologyId)
+                .add("teNodeKeys", teNodeKeys)
+                .add("teLinkKeys", teLinkKeys)
+                .add("topologyData", topologyData)
+                .add("nextTeNodeId", nextTeNodeId)
+                .add("childUpdate", childUpdate)
+                .toString();
+    }
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTerminationPoint.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTerminationPoint.java
new file mode 100644
index 0000000..c40df38
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/InternalTerminationPoint.java
@@ -0,0 +1,112 @@
+/*
+ * 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 java.util.List;
+
+import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
+import org.onosproject.tetopology.management.api.node.TerminationPoint;
+import org.onosproject.tetopology.management.api.node.TerminationPointKey;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+/**
+ * The TerminationPoint representation in store.
+ */
+public class InternalTerminationPoint {
+    private TeLinkTpGlobalKey teTpKey;
+    private List<TerminationPointKey> supportingTpIds;
+
+    /**
+     * Creates an instance of InternalTerminationPoint.
+     *
+     * @param tp the termination point
+     */
+    public InternalTerminationPoint(TerminationPoint tp) {
+        this.supportingTpIds = tp
+                .supportingTpIds() == null ? null
+                                           : Lists.newArrayList(tp
+                                                   .supportingTpIds());
+    }
+
+    /**
+     * Returns the TE termination point key.
+     *
+     * @return the teTpKey
+    */
+    public TeLinkTpGlobalKey teTpKey() {
+        return teTpKey;
+    }
+
+    /**
+     * Returns the supporting termination point Ids.
+     *
+     * @return the supportingTpIds
+     */
+    public List<TerminationPointKey> supportingTpIds() {
+        return supportingTpIds == null ? null
+                                       : ImmutableList.copyOf(supportingTpIds);
+    }
+
+    /**
+     * Sets the TE termination point key.
+     *
+     * @param teTpKey the teTpKey to set
+     */
+    public void setTeTpKey(TeLinkTpGlobalKey teTpKey) {
+        this.teTpKey = teTpKey;
+    }
+
+    /**
+     * Sets the supporting termination point Ids.
+     *
+     * @param supportingTpIds the supportingTpIds to set
+     */
+    public void setSupportingTpIds(List<TerminationPointKey> supportingTpIds) {
+        this.supportingTpIds = supportingTpIds == null ? null
+                                                       : Lists.newArrayList(supportingTpIds);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(supportingTpIds, teTpKey);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof InternalTerminationPoint) {
+            InternalTerminationPoint that = (InternalTerminationPoint) object;
+            return Objects.equal(supportingTpIds, that.supportingTpIds)
+                    && Objects.equal(teTpKey, that.teTpKey);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("supportingTpIds", supportingTpIds)
+                .add("teTpKey", teTpKey)
+                .toString();
+    }
+
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeMgrUtil.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeMgrUtil.java
new file mode 100644
index 0000000..5781663
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeMgrUtil.java
@@ -0,0 +1,231 @@
+/*
+ * 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 java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.MapUtils;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.tetopology.management.api.DefaultNetwork;
+import org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.Network;
+import org.onosproject.tetopology.management.api.TeTopology;
+import org.onosproject.tetopology.management.api.TeTopologyId;
+import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetopology.management.api.link.DefaultNetworkLink;
+import org.onosproject.tetopology.management.api.link.NetworkLink;
+import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
+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.node.DefaultNetworkNode;
+import org.onosproject.tetopology.management.api.node.DefaultTerminationPoint;
+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 com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * TE Topology Manager utility functions.
+ */
+public final class TeMgrUtil {
+    private static final String TENODE_ID = "teNodeId/";
+    private static final String TELINK_ID = "/teLinkId/";
+    private static final String PROVIDER_ID = "providerId/";
+    private static final String CLIENT_ID = "/clientId/";
+    private static final String TOPOLOGY_ID = "/topologyId/";
+
+    // no instantiation
+    private TeMgrUtil() {
+    }
+
+    /**
+     * Returns the network link id for a TE link local key.
+     *
+     * @param  key TE link local key
+     * @return value of network link id
+     */
+    public static KeyId toNetworkLinkId(TeLinkTpKey key) {
+        return KeyId.keyId(new StringBuilder()
+                .append(TENODE_ID)
+                .append(Ip4Address.valueOf((int) key.teNodeId()).toString())
+                .append(TELINK_ID)
+                .append(key.teLinkTpId()).toString());
+    }
+
+    /**
+     * Returns the network id for a TE topology id.
+     *
+     * @param  teTopologyId TE topology id
+     * @return value of network id
+     */
+    public static KeyId toNetworkId(TeTopologyId teTopologyId) {
+        return KeyId.keyId(new StringBuilder()
+                .append(PROVIDER_ID)
+                .append(teTopologyId.providerId())
+                .append(CLIENT_ID)
+                .append(teTopologyId.clientId())
+                .append(TOPOLOGY_ID)
+                .append(teTopologyId.topologyId()).toString());
+    }
+
+    /**
+     * Returns the network id for a TE topology key.
+     *
+     * @param  teTopologyKey TE topology key
+     * @return value of network id
+     */
+    public static KeyId toNetworkId(TeTopologyKey teTopologyKey) {
+        return KeyId.keyId(new StringBuilder()
+                .append(PROVIDER_ID)
+                .append(teTopologyKey.providerId())
+                .append(CLIENT_ID)
+                .append(teTopologyKey.clientId())
+                .append(TOPOLOGY_ID)
+                .append(teTopologyKey.topologyId()).toString());
+    }
+
+    /**
+     * Returns the network node key for a TE node global key.
+     *
+     * @param  teNodeKey TE node global key
+     * @return value of network node key
+     */
+    public static NetworkNodeKey networkNodeKey(TeNodeKey teNodeKey) {
+        return new NetworkNodeKey(toNetworkId(teNodeKey.teTopologyKey()),
+                                  KeyId.keyId(Long.toString(teNodeKey.teNodeId())));
+    }
+
+    /**
+     * Returns the network link key for a TE link global key.
+     *
+     * @param  teLinkKey TE link global key
+     * @return value of network link key
+     */
+    public static NetworkLinkKey networkLinkKey(TeLinkTpGlobalKey teLinkKey) {
+        return new NetworkLinkKey(toNetworkId(teLinkKey.teTopologyKey()),
+                                  toNetworkLinkId(teLinkKey.teLinkTpKey()));
+    }
+
+    /**
+     * Returns the TE topology id for a TE topology.
+     *
+     * @param  teTopology an instance of TE topology
+     * @return value of TE topology id
+     */
+    public static TeTopologyId teTopologyId(TeTopology teTopology) {
+        return new TeTopologyId(teTopology.teTopologyId().providerId(),
+                                teTopology.teTopologyId().clientId(),
+                                teTopology.teTopologyIdStringValue());
+    }
+
+    /**
+     * Returns a default instance of termination point for a TE termination point id.
+     *
+     * @param  teTpId TE termination point id
+     * @return an instance of termination point
+     */
+    private static TerminationPoint tpBuilder(long teTpId) {
+        return new DefaultTerminationPoint(KeyId.keyId(Long.toString(teTpId)), null, teTpId);
+    }
+
+    /**
+     * Returns an instance of network node for a TE node.
+     *
+     * @param id     value of the network node id
+     * @param teNode value of TE node
+     * @return an instance of network node
+     */
+    public static NetworkNode nodeBuilder(KeyId id, TeNode teNode) {
+        List<NetworkNodeKey> supportingNodeIds = null;
+        if (teNode.supportingTeNodeId() != null) {
+            supportingNodeIds = Lists.newArrayList(networkNodeKey(teNode.supportingTeNodeId()));
+        }
+        Map<KeyId, TerminationPoint> tps = Maps.newConcurrentMap();
+        for (Long teTpid : teNode.teTerminationPointIds()) {
+            tps.put(KeyId.keyId(Long.toString(teTpid)), tpBuilder(teTpid));
+        }
+        return new DefaultNetworkNode(id, supportingNodeIds, teNode, tps);
+    }
+
+    /**
+     * Returns the network node termination point key for a TE link end point key.
+     *
+     * @param  teLinkKey TE link end point key
+     * @return value of network node termination point key
+     */
+    public static NodeTpKey nodeTpKey(TeLinkTpKey teLinkKey) {
+        return new NodeTpKey(KeyId.keyId(Long.toString(teLinkKey.teNodeId())),
+                             KeyId.keyId(Long.toString(teLinkKey.teLinkTpId())));
+    }
+
+    /**
+     * Returns an instance of network link for a TE link.
+     *
+     * @param id     value of the network link id
+     * @param teLink value of TE link
+     * @return an instance of network link
+     */
+    public static NetworkLink linkBuilder(KeyId id, TeLink teLink) {
+        NodeTpKey source = nodeTpKey(teLink.teLinkKey());
+        NodeTpKey destination = null;
+        if (teLink.peerTeLinkKey() != null) {
+            destination = nodeTpKey(teLink.peerTeLinkKey());
+        }
+        List<NetworkLinkKey> supportingLinkIds = null;
+        if (teLink.supportingTeLinkId() != null) {
+            supportingLinkIds = Lists.newArrayList(networkLinkKey(teLink.supportingTeLinkId()));
+        }
+        return new DefaultNetworkLink(id, source, destination, supportingLinkIds, teLink);
+    }
+
+    /**
+     * Returns an instance of network for a TE topology.
+     *
+     * @param  teTopology value of TE topology
+     * @return an instance of network
+     */
+    public static Network networkBuilder(TeTopology teTopology) {
+        KeyId networkId = TeMgrUtil.toNetworkId(teTopology.teTopologyId());
+        TeTopologyId topologyId = teTopologyId(teTopology);
+        Map<KeyId, NetworkNode> nodes = null;
+        if (MapUtils.isNotEmpty(teTopology.teNodes())) {
+            nodes = Maps.newHashMap();
+            for (TeNode tenode : teTopology.teNodes().values()) {
+                KeyId key = KeyId.keyId(Long.toString(tenode.teNodeId()));
+                nodes.put(key, nodeBuilder(key, tenode));
+            }
+        }
+        Map<KeyId, NetworkLink> links = null;
+        if (MapUtils.isNotEmpty(teTopology.teLinks())) {
+            links = Maps.newHashMap();
+            for (TeLink telink : teTopology.teLinks().values()) {
+                KeyId key = TeMgrUtil.toNetworkLinkId(telink.teLinkKey());
+                links.put(key, linkBuilder(key, telink));
+
+            }
+        }
+        return new DefaultNetwork(networkId, null, nodes, links,
+                                  topologyId, false, teTopology.ownerId());
+    }
+
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyConfig.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyConfig.java
new file mode 100644
index 0000000..ae2fc0e
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyConfig.java
@@ -0,0 +1,77 @@
+/*
+ * 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 org.onlab.packet.Ip4Address;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.config.basics.ConfigException;
+import org.onosproject.net.config.Config;
+
+/**
+ * Configuration for TE Topology parameters.
+ */
+public class TeTopologyConfig extends Config<ApplicationId>  {
+    private static final String CONFIG_VALUE_ERROR = "Error parsing config value";
+    private static final String PROVIDER_ID = "provider-id";
+    private static final String TENODE_ID_START = "tenode-id-start";
+    private static final String TENODE_ID_END = "tenode-id-end";
+
+    /**
+      * Retrieves TE topology provider identifier.
+      *
+      * @return provider Id
+      * @throws ConfigException if the parameters are not correctly configured
+      * or conversion of the parameters fails
+      */
+    public long providerId() throws ConfigException {
+        try {
+            return object.path(PROVIDER_ID).asLong();
+        } catch (IllegalArgumentException e) {
+            throw new ConfigException(CONFIG_VALUE_ERROR, e);
+        }
+    }
+
+    /**
+     * Retrieves TE node starting IPv4 address.
+     *
+     * @return the IPv4 address
+     * @throws ConfigException if the parameters are not correctly configured
+     * or conversion of the parameters fails
+     */
+   public Ip4Address teNodeIpStart() throws ConfigException {
+       try {
+           return Ip4Address.valueOf(object.path(TENODE_ID_START).asText());
+       } catch (IllegalArgumentException e) {
+           throw new ConfigException(CONFIG_VALUE_ERROR, e);
+       }
+   }
+
+   /**
+    * Retrieves TE node end IPv4 address.
+    *
+    * @return the IPv4 address
+    * @throws ConfigException if the parameters are not correctly configured
+    * or conversion of the parameters fails
+    */
+  public Ip4Address teNodeIpEnd() throws ConfigException {
+      try {
+          return Ip4Address.valueOf(object.path(TENODE_ID_END).asText());
+      } catch (IllegalArgumentException e) {
+          throw new ConfigException(CONFIG_VALUE_ERROR, e);
+      }
+  }
+
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyManager.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyManager.java
new file mode 100644
index 0000000..aeb1fbe
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyManager.java
@@ -0,0 +1,902 @@
+/*
+ * 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 java.util.concurrent.Executors.newFixedThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_ADDED;
+import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UPDATED;
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
+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.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 java.util.BitSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+
+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.packet.Ip4Address;
+import org.onosproject.app.ApplicationException;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.config.basics.ConfigException;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.device.DeviceProviderRegistry;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.link.LinkProviderRegistry;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.provider.AbstractListenerProviderRegistry;
+import org.onosproject.net.provider.AbstractProviderService;
+import org.onosproject.tetopology.management.api.CommonTopologyData;
+import org.onosproject.tetopology.management.api.DefaultNetwork;
+import org.onosproject.tetopology.management.api.DefaultNetworks;
+import org.onosproject.tetopology.management.api.DefaultTeTopologies;
+import org.onosproject.tetopology.management.api.DefaultTeTopology;
+import org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.Network;
+import org.onosproject.tetopology.management.api.Networks;
+import org.onosproject.tetopology.management.api.OptimizationType;
+import org.onosproject.tetopology.management.api.TeConstants;
+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.TeTopologyKey;
+import org.onosproject.tetopology.management.api.TeTopologyListener;
+import org.onosproject.tetopology.management.api.TeTopologyProvider;
+import org.onosproject.tetopology.management.api.TeTopologyProviderRegistry;
+import org.onosproject.tetopology.management.api.TeTopologyProviderService;
+import org.onosproject.tetopology.management.api.TeTopologyService;
+import org.onosproject.tetopology.management.api.link.CommonLinkData;
+import org.onosproject.tetopology.management.api.link.DefaultTeLink;
+import org.onosproject.tetopology.management.api.link.ExternalLink;
+import org.onosproject.tetopology.management.api.link.LinkBandwidth;
+import org.onosproject.tetopology.management.api.link.NetworkLink;
+import org.onosproject.tetopology.management.api.link.NetworkLinkEventSubject;
+import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
+import org.onosproject.tetopology.management.api.link.TeLink;
+import org.onosproject.tetopology.management.api.link.TeLinkEventSubject;
+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.UnderlayPath;
+import org.onosproject.tetopology.management.api.node.CommonNodeData;
+import org.onosproject.tetopology.management.api.node.ConnectivityMatrix;
+import org.onosproject.tetopology.management.api.node.DefaultTeNode;
+import org.onosproject.tetopology.management.api.node.NetworkNode;
+import org.onosproject.tetopology.management.api.node.NetworkNodeEventSubject;
+import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
+import org.onosproject.tetopology.management.api.node.TeNode;
+import org.onosproject.tetopology.management.api.node.TeNodeEventSubject;
+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 org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Implementation of the topology management service.
+ */
+@Component(immediate = true)
+@Service
+public class TeTopologyManager
+    extends AbstractListenerProviderRegistry<TeTopologyEvent, TeTopologyListener,
+                                             TeTopologyProvider, TeTopologyProviderService>
+    implements TeTopologyService, TeTopologyProviderRegistry {
+    private static final String APP_NAME = "org.onosproject.tetopology";
+    public static final long DEFAULT_PROVIDER_ID = 0x0a0a0a0aL;
+    private static final long DEFAULT_CLIENT_ID = 0x00L;
+    private long providerId = DEFAULT_PROVIDER_ID;
+    private static final int MAX_THREADS = 1;
+
+    private static final Ip4Address DEFAULT_TENODE_ID_START = Ip4Address.valueOf("1.1.1.1");
+    private static final Ip4Address DEFAULT_TENODE_ID_END = Ip4Address.valueOf("250.250.250.250");
+    private Ip4Address teNodeIpStart = DEFAULT_TENODE_ID_START;
+    private Ip4Address teNodeIpEnd = DEFAULT_TENODE_ID_END;
+    private long nextTeNodeId = teNodeIpStart.toInt();
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry cfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceProviderRegistry deviceProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkProviderRegistry linkProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public TeTopologyStore store;
+
+    private TeTopologyStoreDelegate delegate = this::post;
+    private final BlockingQueue<TeTopologyEvent> eventQueue = new LinkedBlockingQueue<>();
+    private final BlockingQueue<TeTopologyMapEvent> mapEventQueue = new LinkedBlockingQueue<>();
+    private final ConfigFactory<ApplicationId, TeTopologyConfig> factory =
+            new ConfigFactory<ApplicationId, TeTopologyConfig>(APP_SUBJECT_FACTORY,
+                    TeTopologyConfig.class,
+                    "teTopologyCfg",
+                    false) {
+        @Override
+        public TeTopologyConfig createConfig() {
+            return new TeTopologyConfig();
+        }
+    };
+    private final NetworkConfigListener cfgLister = new InternalConfigListener();
+    private ApplicationId appId;
+    // The topology merged in MDSC
+    private TeTopology mergedTopology = null;
+    private TeTopologyKey mergedTopologyKey;
+    private Network mergedNetwork = null;
+    // Track new TE node id by its source TE node key
+    private Map<TeNodeKey, Long> sourceNewTeNodeIdMap = Maps.newHashMap();
+    // Track the external link keys by the plugId
+    private Map<Long, LinkKeyPair> externalLinkMap = Maps.newHashMap();
+    private ExecutorService executor;
+
+    /**
+     * Activation helper function.
+     */
+    public void activateBasics() {
+        store.setDelegate(delegate);
+        store.setMapEventQueue(mapEventQueue);
+        eventDispatcher.addSink(TeTopologyEvent.class, listenerRegistry);
+    }
+
+    /**
+     * Deactivation helper function.
+     */
+    public void deactivateBasics() {
+        store.unsetDelegate(delegate);
+        eventDispatcher.removeSink(TeTopologyEvent.class);
+    }
+
+    @Activate
+    public void activate() {
+        activateBasics();
+        appId = coreService.registerApplication(APP_NAME);
+        cfgService.registerConfigFactory(factory);
+        executor = newFixedThreadPool(MAX_THREADS, groupedThreads("onos/tetopology", "build-%d", log));
+
+        cfgService.addListener(cfgLister);
+        executor.execute(new TopologyMergerTask());
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        deactivateBasics();
+        externalLinkMap.clear();
+        cfgService.removeListener(cfgLister);
+        cfgService.unregisterConfigFactory(factory);
+        executor.shutdownNow();
+        executor = null;
+        eventQueue.clear();
+        log.info("Stopped");
+    }
+
+    @Override
+    protected TeTopologyProviderService createProviderService(TeTopologyProvider provider) {
+        return new InternalTopologyProviderService(provider);
+    }
+
+    private class InternalTopologyProviderService
+                      extends AbstractProviderService<TeTopologyProvider>
+                      implements TeTopologyProviderService {
+
+        protected InternalTopologyProviderService(TeTopologyProvider provider) {
+            super(provider);
+        }
+
+        @Override
+        public void networkUpdated(Network network) {
+            store.updateNetwork(network);
+        }
+
+        @Override
+        public void networkRemoved(KeyId networkId) {
+            store.removeNetwork(networkId);
+        }
+
+        @Override
+        public void linkUpdated(NetworkLinkKey linkKey, NetworkLink link) {
+            store.updateNetworkLink(linkKey, link);
+        }
+
+        @Override
+        public void linkRemoved(NetworkLinkKey linkKey) {
+            store.removeNetworkLink(linkKey);
+        }
+
+        @Override
+        public void nodeUpdated(NetworkNodeKey nodeKey, NetworkNode node) {
+            store.updateNetworkNode(nodeKey, node);
+        }
+
+        @Override
+        public void nodeRemoved(NetworkNodeKey nodeKey) {
+            store.removeNetworkNode(nodeKey);
+        }
+
+        @Override
+        public void terminationPointUpdated(TerminationPointKey terminationPointKey,
+                TerminationPoint terminationPoint) {
+            store.updateTerminationPoint(terminationPointKey, terminationPoint);
+        }
+
+        @Override
+        public void terminationPointRemoved(TerminationPointKey terminationPointKey) {
+            store.removeTerminationPoint(terminationPointKey);
+        }
+    }
+
+    private boolean isCustomizedLearnedTopology(TeTopologyKey key) {
+        if (store.teTopology(key).flags().get(TeTopology.BIT_CUSTOMIZED) &&
+                store.teTopology(key).flags().get(TeTopology.BIT_LEARNT)) {
+            return true;
+        }
+        return false;
+    }
+
+    // Task for merge the learned topology.
+    private class TopologyMergerTask implements Runnable {
+
+        public TopologyMergerTask() {
+        }
+
+        @Override
+        public void run() {
+            try {
+                TeTopologyMapEvent event;
+                while ((event = mapEventQueue.take()) != null) {
+                    switch (event.type()) {
+                    case TE_TOPOLOGY_ADDED:
+                    case TE_TOPOLOGY_UPDATED:
+                        TeTopology teTopology = store.teTopology(event.teTopologyKey());
+                        post(new TeTopologyEvent(event.type(), teTopology));
+                        if (event.type() == TE_TOPOLOGY_ADDED &&
+                                teTopology.flags().get(TeTopology.BIT_CUSTOMIZED) &&
+                                teTopology.flags().get(TeTopology.BIT_LEARNT)) {
+                            mergeTopology(teTopology);
+                        }
+                        break;
+                    case TE_TOPOLOGY_REMOVED:
+                        post(new TeTopologyEvent(TE_TOPOLOGY_REMOVED,
+                                                 new DefaultTeTopology(event.teTopologyKey(),
+                                                                      null, null, null, null)));
+                        break;
+                    case TE_NODE_ADDED:
+                    case TE_NODE_UPDATED:
+                        TeNode teNode = store.teNode(event.teNodeKey());
+                        post(new TeTopologyEvent(event.type(),
+                                                 new TeNodeEventSubject(event.teNodeKey(), teNode)));
+                        if (isCustomizedLearnedTopology(event.teNodeKey().teTopologyKey())) {
+                            updateSourceTeNode(mergedTopology.teNodes(),
+                                               event.teNodeKey().teTopologyKey(), teNode, true);
+                        }
+                        break;
+                    case TE_NODE_REMOVED:
+                        post(new TeTopologyEvent(TE_NODE_REMOVED,
+                                                 new TeNodeEventSubject(event.teNodeKey(), null)));
+                        if (isCustomizedLearnedTopology(event.teNodeKey().teTopologyKey())) {
+                            removeSourceTeNode(mergedTopology.teNodes(), event.teNodeKey(), true);
+                        }
+                        break;
+                    case TE_LINK_ADDED:
+                    case TE_LINK_UPDATED:
+                        TeLink teLink = store.teLink(event.teLinkKey());
+                        post(new TeTopologyEvent(event.type(),
+                                                 new TeLinkEventSubject(event.teLinkKey(), teLink)));
+                        if (isCustomizedLearnedTopology(event.teLinkKey().teTopologyKey())) {
+                            Map<TeLinkTpKey, TeLink> teLinks = Maps.newHashMap(mergedTopology.teLinks());
+                            updateSourceTeLink(teLinks, event.teLinkKey().teTopologyKey(), teLink, true);
+                            updateMergedTopology(mergedTopology.teNodes(), teLinks);
+                        }
+                        break;
+                    case TE_LINK_REMOVED:
+                        post(new TeTopologyEvent(TE_LINK_REMOVED,
+                                                 new TeLinkEventSubject(event.teLinkKey(), null)));
+                        if (isCustomizedLearnedTopology(event.teLinkKey().teTopologyKey())) {
+                            Map<TeLinkTpKey, TeLink> teLinks = Maps.newHashMap(mergedTopology.teLinks());
+                            removeSourceTeLink(teLinks, event.teLinkKey(), true);
+                            updateMergedTopology(mergedTopology.teNodes(), teLinks);
+                        }
+                        break;
+                    case NETWORK_ADDED:
+                    case NETWORK_UPDATED:
+                        Network network = store.network(event.networkKey());
+                        post(new TeTopologyEvent(event.type(), network));
+                        break;
+                    case NETWORK_REMOVED:
+                        post(new TeTopologyEvent(NETWORK_REMOVED,
+                                                 new DefaultNetwork(event.networkKey(),
+                                                                    null, null, null, null, false, null)));
+                        break;
+                    case NODE_ADDED:
+                    case NODE_UPDATED:
+                        NetworkNode node = store.networkNode(event.networkNodeKey());
+                        post(new TeTopologyEvent(event.type(),
+                                                 new NetworkNodeEventSubject(event.networkNodeKey(), node)));
+                        break;
+                    case NODE_REMOVED:
+                        post(new TeTopologyEvent(NODE_REMOVED,
+                                                 new NetworkNodeEventSubject(event.networkNodeKey(), null)));
+                        break;
+                    case LINK_ADDED:
+                    case LINK_UPDATED:
+                        NetworkLink link = store.networkLink(event.networkLinkKey());
+                        post(new TeTopologyEvent(event.type(),
+                                                 new NetworkLinkEventSubject(event.networkLinkKey(), link)));
+                        break;
+                    case LINK_REMOVED:
+                        post(new TeTopologyEvent(LINK_REMOVED,
+                                                 new NetworkLinkEventSubject(event.networkLinkKey(), null)));
+                        break;
+                    default:
+                        break;
+                    }
+                }
+            } catch (InterruptedException e) {
+                log.warn("TopologyMergerTask is interrupted");
+            } catch (Exception e) {
+                log.warn("Unable to merge topology", e);
+            }
+        }
+    }
+
+    private void removeSourceTeNode(Map<Long, TeNode> teNodes,
+                                    TeNodeKey srcNodeKey, boolean postEvent) {
+       Long mergedTeNodeId = sourceNewTeNodeIdMap.remove(srcNodeKey);
+       if (mergedTeNodeId == null) {
+           return;
+       }
+       if (teNodes.remove(mergedTeNodeId) != null && postEvent) {
+           post(new TeTopologyEvent(TE_NODE_REMOVED,
+                                    new TeNodeEventSubject(
+                                            new TeNodeKey(mergedTopologyKey,
+                                                          mergedTeNodeId),
+                                            null)));
+       }
+    }
+
+    private void updateSourceTeNode(Map<Long, TeNode> teNodes, TeTopologyKey srcTopoKey,
+                                    TeNode srcNode, boolean postEvent) {
+        TeNodeKey sourceTeNodeId = new TeNodeKey(srcTopoKey, srcNode.teNodeId());
+        Long mergedTeNodeId = sourceNewTeNodeIdMap.get(sourceTeNodeId);
+        boolean addNode = false;
+        if (mergedTeNodeId == null) {
+            // New node
+            addNode = true;
+            mergedTeNodeId = nextTeNodeId;
+            nextTeNodeId++;
+            if (nextTeNodeId >= teNodeIpEnd.toInt()) {
+                nextTeNodeId = teNodeIpStart.toInt();
+                log.warn("TE node Id is wrapped back");
+            }
+            sourceNewTeNodeIdMap.put(sourceTeNodeId, mergedTeNodeId);
+        }
+        TeTopologyKey underlayTopologyId = null; // No underlay
+        TeNodeKey supportTeNodeId = null; // No supporting
+
+        CommonNodeData common = new CommonNodeData(srcNode.name(), srcNode.adminStatus(),
+                                                   srcNode.opStatus(), srcNode.flags()); // No change
+        Map<Long, ConnectivityMatrix> connMatrices = srcNode.connectivityMatrices();
+        List<Long> teLinkIds = srcNode.teLinkIds(); // No change
+        Map<Long, TunnelTerminationPoint> ttps = srcNode.tunnelTerminationPoints();
+        List<Long> teTpIds = srcNode.teTerminationPointIds(); // No change
+        DefaultTeNode newNode = new DefaultTeNode(mergedTeNodeId, underlayTopologyId,
+                supportTeNodeId, sourceTeNodeId, common, connMatrices, teLinkIds,
+                ttps, teTpIds);
+        teNodes.put(mergedTeNodeId, newNode);
+        if (postEvent) {
+            //Post event for the TE node in the merged topology
+            TeNodeKey globalKey = new TeNodeKey(mergedTopologyKey, mergedTeNodeId);
+            post(new TeTopologyEvent(addNode ? TE_NODE_ADDED : TE_NODE_UPDATED,
+                                     new TeNodeEventSubject(globalKey, newNode)));
+            post(new TeTopologyEvent(addNode ? NODE_ADDED : NODE_UPDATED,
+                                     new NetworkNodeEventSubject(TeMgrUtil.networkNodeKey(globalKey),
+                                             TeMgrUtil.nodeBuilder(
+                                                     KeyId.keyId(Long.toString(newNode.teNodeId())),
+                                                     newNode))));
+        }
+    }
+
+    // Merge TE nodes
+    private void mergeNodes(Map<Long, TeNode> nodes, TeTopology topology) {
+
+        if (!MapUtils.isEmpty(topology.teNodes())) {
+            for (Map.Entry<Long, TeNode> entry : topology.teNodes().entrySet()) {
+                updateSourceTeNode(nodes, topology.teTopologyId(), entry.getValue(),
+                                   mergedTopology != null);
+            }
+        }
+    }
+
+    // Returns a new TeLink based on an existing TeLink with new attributes
+    private TeLink updateTeLink(TeLinkTpKey newKey, TeLinkTpKey peerTeLinkKey,
+            TeTopologyKey underlayTopologyId, TeLinkTpGlobalKey supportTeLinkId,
+            TeLinkTpGlobalKey sourceTeLinkId, ExternalLink externalLink,
+            TeLink exLink) {
+        UnderlayPath underlayPath = new UnderlayPath(exLink.primaryPath(),
+                exLink.backupPaths(), exLink.tunnelProtectionType(),
+                exLink.sourceTtpId(), exLink.destinationTtpId(),
+                exLink.teTunnelId()
+                );
+        TePathAttributes teAttributes = new TePathAttributes(exLink.cost(),
+                exLink.delay(), exLink.srlgs());
+        LinkBandwidth bandwidth = new LinkBandwidth(exLink.maxBandwidth(),
+                                                    exLink.availBandwidth(),
+                                                    exLink.maxAvailLspBandwidth(),
+                                                    exLink.minAvailLspBandwidth(),
+                                                    exLink.oduResource());
+        CommonLinkData common = new CommonLinkData(exLink.adminStatus(), exLink.opStatus(),
+                exLink.flags(), exLink.switchingLayer(), exLink.encodingLayer(),
+                externalLink, underlayPath, teAttributes,
+                exLink.administrativeGroup(), exLink.interLayerLocks(),
+                bandwidth);
+        return new DefaultTeLink(newKey, peerTeLinkKey, underlayTopologyId,
+                supportTeLinkId, sourceTeLinkId, common);
+    }
+
+    private class LinkKeyPair {
+        private TeLinkTpKey firstKey;
+        private TeLinkTpKey secondKey;
+
+        public LinkKeyPair(TeLinkTpKey firstKey) {
+            this.firstKey = firstKey;
+        }
+
+        public TeLinkTpKey firstKey() {
+            return firstKey;
+        }
+
+        public void setFirstKey(TeLinkTpKey firstKey) {
+            this.firstKey = firstKey;
+        }
+
+        public TeLinkTpKey secondKey() {
+            return secondKey;
+        }
+
+        public void setSecondKey(TeLinkTpKey secondKey) {
+            this.secondKey = secondKey;
+        }
+
+        @Override
+        public String toString() {
+            return MoreObjects.toStringHelper(this)
+                    .add("firstKey", firstKey)
+                    .add("secondKey", secondKey)
+                    .toString();
+        }
+    }
+
+    private void removeSourceTeLink(Map<TeLinkTpKey, TeLink> teLinks, TeLinkTpGlobalKey teLinkKey,
+                                    boolean postEvent) {
+        TeNodeKey sourceTeNodeKey = teLinkKey.teNodeKey();
+        Long newTeNodeId = sourceNewTeNodeIdMap.get(sourceTeNodeKey);
+        if (newTeNodeId == null) {
+            return;
+        }
+        TeLinkTpKey newLinkKey = new TeLinkTpKey(newTeNodeId, teLinkKey.teLinkTpId());
+        TeLink teLink = teLinks.remove(newLinkKey);
+        if (teLink == null) {
+            return;
+        }
+        //Post event
+        if (postEvent) {
+            post(new TeTopologyEvent(TE_LINK_REMOVED,
+                                     new TeLinkEventSubject(
+                                             new TeLinkTpGlobalKey(mergedTopologyKey,
+                                                                   newLinkKey),
+                                             null)));
+        }
+
+        if (teLink.externalLink() != null && teLink.externalLink().plugId() != null) {
+            // Update the LinkKeyPair in externalLinkMap
+            LinkKeyPair pair = externalLinkMap.get(teLink.externalLink().plugId());
+            if (pair != null && pair.firstKey() != null &&
+                    pair.firstKey().equals(newLinkKey)) {
+                pair.setFirstKey(null);
+            } else if (pair != null && pair.secondKey() != null &&
+                    pair.secondKey().equals(newLinkKey)) {
+                pair.setSecondKey(null);
+            }
+            if (pair != null && pair.firstKey() == null &&
+                    pair.secondKey() == null) {
+                externalLinkMap.remove(teLink.externalLink().plugId());
+            }
+        }
+        TeLinkTpKey peerTeLinkKey = teLink.peerTeLinkKey();
+        if (peerTeLinkKey != null) {
+            // Update peerLink's peerTeLinkKey to null
+            TeLink peerLink = teLinks.get(peerTeLinkKey);
+            if (peerLink == null) {
+                return;
+            }
+            TeLink newPeerLink = updateTeLink(peerTeLinkKey, null,
+                                       peerLink.underlayTeTopologyId(), peerLink.supportingTeLinkId(),
+                                       peerLink.sourceTeLinkId(), peerLink.externalLink(), peerLink);
+            teLinks.put(peerTeLinkKey, newPeerLink);
+            if (postEvent) {
+                post(new TeTopologyEvent(TE_LINK_UPDATED,
+                                         new TeLinkEventSubject(
+                                                 new TeLinkTpGlobalKey(mergedTopologyKey,
+                                                                       peerTeLinkKey),
+                                                 newPeerLink)));
+            }
+        }
+    }
+
+    private void updateSourceTeLink(Map<TeLinkTpKey, TeLink> teLinks, TeTopologyKey srcTopoKey,
+                                    TeLink srcLink, boolean postEvent) {
+        TeNodeKey sourceTeNodeId = new TeNodeKey(srcTopoKey,
+                                                 srcLink.teLinkKey().teNodeId());
+        TeLinkTpKey newKey = new TeLinkTpKey(
+                sourceNewTeNodeIdMap.get(sourceTeNodeId),
+                srcLink.teLinkKey().teLinkTpId());
+        TeLinkTpKey peerTeLinkKey = null;
+        if (srcLink.peerTeLinkKey() != null) {
+            TeNodeKey sourcePeerNode = new TeNodeKey(srcTopoKey,
+                                                     srcLink.peerTeLinkKey().teNodeId());
+            peerTeLinkKey = new TeLinkTpKey(
+                    sourceNewTeNodeIdMap.get(sourcePeerNode),
+                    srcLink.peerTeLinkKey().teLinkTpId());
+        }
+
+        if (srcLink.externalLink() != null &&
+                srcLink.externalLink().plugId() != null) {
+            // externalLinkKey doesn't have topology Id.
+            // using plugId for now
+            LinkKeyPair pair = externalLinkMap.get(srcLink.externalLink().plugId());
+            if (pair != null) {
+                if (pair.firstKey() == null) {
+                    peerTeLinkKey = pair.secondKey;
+                    pair.setFirstKey(newKey);
+                } else {
+                    peerTeLinkKey = pair.firstKey;
+                    pair.setSecondKey(newKey);
+                }
+
+                TeLink peerLink = teLinks.get(peerTeLinkKey);
+                if (peerLink != null) {
+                    // Update peer Link with local link key
+                    TeLink newPeerLink = updateTeLink(peerTeLinkKey, newKey,
+                                                      peerLink.underlayTeTopologyId(),
+                                                      peerLink.supportingTeLinkId(),
+                                                      peerLink.sourceTeLinkId(),
+                                                      peerLink.externalLink(), peerLink);
+                    teLinks.put(peerTeLinkKey, newPeerLink);
+                    if (postEvent) {
+                        post(new TeTopologyEvent(TE_LINK_UPDATED,
+                                                 new TeLinkEventSubject(
+                                                         new TeLinkTpGlobalKey(mergedTopologyKey,
+                                                                               peerTeLinkKey),
+                                                         newPeerLink)));
+                    }
+
+               }
+            } else {
+                // Store it in the map
+                externalLinkMap.put(srcLink.externalLink().plugId(), new LinkKeyPair(newKey));
+            }
+        }
+
+        TeTopologyKey underlayTopologyId = null; // No underlay
+        TeLinkTpGlobalKey supportTeLinkId = null; // No support
+        // Source link for the new updated link
+        TeLinkTpGlobalKey sourceTeLinkId = new TeLinkTpGlobalKey(srcTopoKey, srcLink.teLinkKey());
+        TeLink updatedLink = updateTeLink(newKey, peerTeLinkKey, underlayTopologyId,
+                                      supportTeLinkId, sourceTeLinkId,
+                                      srcLink.externalLink(), srcLink);
+        TeLinkTpGlobalKey newGlobalKey = new TeLinkTpGlobalKey(mergedTopologyKey, newKey);
+        boolean newLink = teLinks.get(newGlobalKey) == null ? true : false;
+        teLinks.put(newKey, updatedLink);
+        if (postEvent) {
+            //Post event
+            post(new TeTopologyEvent(newLink ? TE_LINK_ADDED : TE_LINK_UPDATED,
+                                     new TeLinkEventSubject(newGlobalKey, updatedLink)));
+            post(new TeTopologyEvent(newLink ? LINK_ADDED : LINK_UPDATED,
+                                     new NetworkLinkEventSubject(TeMgrUtil.networkLinkKey(newGlobalKey),
+                                             TeMgrUtil.linkBuilder(TeMgrUtil.toNetworkLinkId(
+                                                                          updatedLink.teLinkKey()),
+                                                                   updatedLink))));
+        }
+    }
+
+    // Merge TE links
+    private void mergeLinks(Map<TeLinkTpKey, TeLink> teLinks, TeTopology topology) {
+        if (!MapUtils.isEmpty(topology.teLinks())) {
+            for (Map.Entry<TeLinkTpKey, TeLink> entry : topology.teLinks().entrySet()) {
+                TeLink srcLink = entry.getValue();
+                updateSourceTeLink(teLinks, topology.teTopologyId(), srcLink,
+                                   mergedTopology != null);
+            }
+        }
+    }
+
+    // Update the merged topology with new TE nodes and links
+    private void updateMergedTopology(Map<Long, TeNode> teNodes, Map<TeLinkTpKey, TeLink> teLinks) {
+        boolean newTopology = mergedTopology == null;
+        BitSet flags = newTopology ? new BitSet(TeConstants.FLAG_MAX_BITS) : mergedTopology.flags();
+        flags.set(TeTopology.BIT_MERGED);
+        CommonTopologyData commonData  = new CommonTopologyData(newTopology ?
+                                                                TeMgrUtil.toNetworkId(mergedTopologyKey) :
+                                                                mergedTopology.networkId(),
+                                                                OptimizationType.NOT_OPTIMIZED,
+                                                                flags, DeviceId.deviceId("localHost"));
+        mergedTopology = new DefaultTeTopology(mergedTopologyKey, teNodes, teLinks,
+                                               Long.toString(mergedTopologyKey.topologyId()), commonData);
+        mergedNetwork = TeMgrUtil.networkBuilder(mergedTopology);
+        log.info("Nodes# {}, Links# {}", mergedTopology.teNodes().size(), mergedTopology.teLinks().size());
+    }
+
+    // Merge the new learned topology
+    private void mergeTopology(TeTopology topology) {
+        boolean newTopology = mergedTopology == null;
+        mergedTopologyKey = newTopology ?
+                            new TeTopologyKey(providerId, DEFAULT_CLIENT_ID,
+                                              store.nextTeTopologyId()) :
+                            mergedTopology.teTopologyId();
+
+        Map<Long, TeNode> teNodes = newTopology || mergedTopology.teNodes() == null ?
+                Maps.newHashMap() : Maps.newHashMap(mergedTopology.teNodes());
+        mergeNodes(teNodes, topology);
+        Map<TeLinkTpKey, TeLink> teLinks = newTopology || mergedTopology.teLinks() == null ?
+                Maps.newHashMap() : Maps.newHashMap(mergedTopology.teLinks());
+        mergeLinks(teLinks, topology);
+        updateMergedTopology(teNodes, teLinks);
+        log.info("mergedTopology {}", mergedTopology);
+
+        if (newTopology) {
+            // Post events for the merged network topology;
+            post(new TeTopologyEvent(TE_TOPOLOGY_ADDED, mergedTopology));
+            post(new TeTopologyEvent(NETWORK_ADDED, mergedNetwork));
+        }
+    }
+
+    private TeTopologyKey newTeTopologyKey(TeTopology teTopology) {
+        TeTopologyKey key = teTopology.teTopologyId();
+        if (key == null || teTopology.teTopologyIdStringValue() == null) {
+            log.error("Ignoring the non-TE topology");
+            throw new ApplicationException("Missing TE topology ID");
+        }
+        // Get the topologyId numeric value
+        long idValue = key.topologyId();
+        if (idValue == TeConstants.NIL_LONG_VALUE) {
+            if (teTopology.teTopologyIdStringValue() != null) {
+                try {
+                    idValue = Long.parseLong(teTopology.teTopologyIdStringValue());
+                } catch (NumberFormatException e) {
+                    // Can't get the long value from the string.
+                    // Use an assigned id value from local id pool,
+                    idValue = store.nextTeTopologyId();
+                }
+                return new TeTopologyKey(key.providerId(), key.clientId(), idValue);
+            }
+        }
+        return null;
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            try {
+                providerId = cfgService.getConfig(appId, TeTopologyConfig.class)
+                                       .providerId();
+                teNodeIpStart = cfgService.getConfig(appId, TeTopologyConfig.class)
+                                          .teNodeIpStart();
+                teNodeIpEnd = cfgService.getConfig(appId, TeTopologyConfig.class)
+                                        .teNodeIpEnd();
+                nextTeNodeId = teNodeIpStart.toInt();
+            } catch (ConfigException e) {
+                log.error("Configuration error {}", e);
+            }
+        }
+
+        @Override
+        public boolean isRelevant(NetworkConfigEvent event) {
+            return event.configClass().equals(TeTopologyConfig.class) &&
+                    (event.type() == CONFIG_ADDED ||
+                    event.type() == CONFIG_UPDATED);
+        }
+    }
+
+    @Override
+    public TeTopologies teTopologies() {
+        Map<TeTopologyKey, TeTopology> map;
+        if (MapUtils.isNotEmpty(store.teTopologies().teTopologies())) {
+            map = Maps.newHashMap(store.teTopologies().teTopologies());
+        } else {
+            map = Maps.newHashMap();
+        }
+        if (mergedTopology != null) {
+            map.put(mergedTopologyKey, mergedTopology);
+        }
+        return new DefaultTeTopologies(store.teTopologies().name(), map);
+    }
+
+    @Override
+    public TeTopology teTopology(TeTopologyKey topologyId) {
+        if (mergedTopology != null &&
+                topologyId.equals(mergedTopologyKey)) {
+            return mergedTopology;
+        }
+        return store.teTopology(topologyId);
+    }
+
+    @Override
+    public TeTopology mergedTopology() {
+        return mergedTopology;
+    }
+
+    @Override
+    public void updateTeTopology(TeTopology teTopology) {
+        TeTopologyKey newKey = null;
+        try {
+            newKey = newTeTopologyKey(teTopology);
+        } catch (ApplicationException e) {
+            log.error("Ignoring the non-TE topology");
+            return;
+        }
+
+        // TE topology is updated here from other APP or NBI, the flag
+        // BIT_CUSTOMIZED or BIT_MERGED should be set.
+        BitSet flags = teTopology.flags();
+        if (flags == null ||
+                !(flags.get(TeTopology.BIT_CUSTOMIZED) ||
+                  flags.get(TeTopology.BIT_MERGED))) {
+            log.error("TE topology flags {} are not set properly", flags);
+            return;
+        }
+
+        if (newKey != null) {
+            DefaultTeTopology newTopology = new DefaultTeTopology(
+                    newKey == null ? teTopology.teTopologyId() : newKey,
+                    teTopology.teNodes(), teTopology.teLinks(),
+                    teTopology.teTopologyIdStringValue(), new CommonTopologyData(teTopology));
+            // Update with new data
+            store.updateTeTopology(newTopology);
+        } else {
+            store.updateTeTopology(teTopology);
+        }
+    }
+
+    @Override
+    public void removeTeTopology(TeTopologyKey topologyId) {
+        store.removeTeTopology(topologyId);
+    }
+
+    @Override
+    public Networks networks() {
+        List<Network> networks;
+        if (CollectionUtils.isNotEmpty(store.networks())) {
+            networks = Lists.newArrayList(store.networks());
+        } else {
+            networks = Lists.newArrayList();
+        }
+        if (mergedNetwork != null) {
+            networks.add(mergedNetwork);
+        }
+        return new DefaultNetworks(networks);
+    }
+
+    @Override
+    public Network network(KeyId networkId) {
+        if (mergedNetwork != null &&
+                mergedNetwork.networkId().equals(networkId)) {
+            return mergedNetwork;
+        }
+        return store.network(networkId);
+    }
+
+    @Override
+    public void updateNetwork(Network network) {
+        // TODO: This will be implemented if required.
+    }
+
+    @Override
+    public void removeNetwork(KeyId networkId) {
+        // TODO: This will be implemented if required.
+    }
+
+    @Override
+    public TeNode teNode(TeNodeKey nodeId) {
+        if (nodeId.teTopologyKey().equals(mergedTopologyKey)) {
+            return mergedTopology.teNode(nodeId.teNodeId());
+        }
+        return store.teNode(nodeId);
+    }
+
+    @Override
+    public TeLink teLink(TeLinkTpGlobalKey linkId) {
+        if (linkId.teTopologyKey().equals(mergedTopologyKey)) {
+            return mergedTopology.teLink(linkId.teLinkTpKey());
+        }
+        return store.teLink(linkId);
+    }
+
+    @Override
+    public TunnelTerminationPoint tunnelTerminationPoint(TtpKey ttpId) {
+        if (ttpId.teTopologyKey().equals(mergedTopologyKey)) {
+            return mergedTopology.teNode(ttpId.teNodeId())
+                    .tunnelTerminationPoint(ttpId.ttpId());
+        }
+        return store.tunnelTerminationPoint(ttpId);
+    }
+
+    @Override
+    public KeyId networkId(TeTopologyKey teTopologyKey) {
+        return store.networkId(teTopologyKey);
+    }
+
+    @Override
+    public NetworkNodeKey nodeKey(TeNodeKey teNodeKey) {
+        return store.nodeKey(teNodeKey);
+    }
+
+    @Override
+    public NetworkLinkKey linkKey(TeLinkTpGlobalKey teLinkKey) {
+        return store.linkKey(teLinkKey);
+    }
+
+    @Override
+    public TerminationPointKey terminationPointKey(TeLinkTpGlobalKey teTpKey) {
+        return store.terminationPointKey(teTpKey);
+    }
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyMapEvent.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyMapEvent.java
new file mode 100644
index 0000000..a88ab51
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyMapEvent.java
@@ -0,0 +1,176 @@
+/*
+ * 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 org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.TeTopologyEvent.Type;
+import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
+import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
+import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+
+import com.google.common.base.MoreObjects;
+
+public class TeTopologyMapEvent {
+    private final Type type;
+    private TeTopologyKey teTopologyKey;
+    private TeNodeKey teNodeKey;
+    private TeLinkTpGlobalKey teLinkKey;
+    private KeyId networkKey;
+    private NetworkNodeKey networkNodeKey;
+    private NetworkLinkKey networkLinkKey;
+
+    /**
+     * Creates an instance of TeTopologyMapEvent.
+     *
+     * @param type the map event type
+     */
+    public TeTopologyMapEvent(Type type) {
+        this.type = type;
+    }
+
+    /**
+     * Returns the map event type.
+     *
+     * @return the type
+     */
+    public Type type() {
+        return type;
+    }
+
+    /**
+     * Returns the TE topology key of the event.
+     *
+     * @return the teTopologyKey
+     */
+    public TeTopologyKey teTopologyKey() {
+        return teTopologyKey;
+    }
+
+    /**
+     * Sets the TE topology key of the event.
+     *
+     * @param teTopologyKey the teTopologyKey to set
+     */
+    public void setTeTopologyKey(TeTopologyKey teTopologyKey) {
+        this.teTopologyKey = teTopologyKey;
+    }
+
+    /**
+     * Returns the TE node key of the event.
+     *
+     * @return the teNodeKey
+     */
+    public TeNodeKey teNodeKey() {
+        return teNodeKey;
+    }
+
+    /**
+     * Sets the TE node key of the event.
+     *
+     * @param teNodeKey the teNodeKey to set
+     */
+    public void setTeNodeKey(TeNodeKey teNodeKey) {
+        this.teNodeKey = teNodeKey;
+    }
+
+    /**
+     * Returns the TE link key of the event.
+     *
+     * @return the teLinkKey
+     */
+    public TeLinkTpGlobalKey teLinkKey() {
+        return teLinkKey;
+    }
+
+    /**
+     * Sets the TE link key of the event.
+     *
+     * @param teLinkKey the teLinkKey to set
+     */
+    public void setTeLinkKey(TeLinkTpGlobalKey teLinkKey) {
+        this.teLinkKey = teLinkKey;
+    }
+
+    /**
+     * Returns the network key of the event.
+     *
+     * @return the networkKey
+     */
+    public KeyId networkKey() {
+        return networkKey;
+    }
+
+    /**
+     * Sets the network key of the event.
+     *
+     * @param networkKey the networkKey to set
+     */
+    public void setNetworkKey(KeyId networkKey) {
+        this.networkKey = networkKey;
+    }
+
+    /**
+     * Returns the network node key of the event.
+     *
+     * @return the networkNodeKey
+     */
+    public NetworkNodeKey networkNodeKey() {
+        return networkNodeKey;
+    }
+
+    /**
+     * Sets the network node key of the event.
+     *
+     * @param networkNodeKey the networkNodeKey to set
+     */
+    public void setNetworkNodeKey(NetworkNodeKey networkNodeKey) {
+        this.networkNodeKey = networkNodeKey;
+    }
+
+    /**
+     * Returns the network link key of the event.
+     *
+     * @return the networkLinkKey
+     */
+    public NetworkLinkKey networkLinkKey() {
+        return networkLinkKey;
+    }
+
+    /**
+     * Sets the network link key of the event.
+     *
+     * @param networkLinkKey the networkLinkKey to set
+     */
+    public void setNetworkLinkKey(NetworkLinkKey networkLinkKey) {
+        this.networkLinkKey = networkLinkKey;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("type", type)
+                .add("teTopologyKey", teTopologyKey)
+                .add("teNodeKey", teNodeKey)
+                .add("teLinkKey", teLinkKey)
+                .add("networkKey", networkKey)
+                .add("networkNodeKey", networkNodeKey)
+                .add("networkLinkKey", networkLinkKey)
+                .toString();
+    }
+
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyStore.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyStore.java
new file mode 100644
index 0000000..9ba407a
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyStore.java
@@ -0,0 +1,283 @@
+/*
+ * 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 java.util.List;
+import java.util.concurrent.BlockingQueue;
+
+import org.onosproject.store.Store;
+import org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.Network;
+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.TeTopologyKey;
+import org.onosproject.tetopology.management.api.link.NetworkLink;
+import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
+import org.onosproject.tetopology.management.api.link.TeLink;
+import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
+import org.onosproject.tetopology.management.api.node.NetworkNode;
+import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
+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;
+
+/**
+ * Inventory of TE network topology.
+ */
+public interface TeTopologyStore
+        extends Store<TeTopologyEvent, TeTopologyStoreDelegate> {
+
+    /**
+     * Returns a collection of currently known networks.
+     *
+     * @return a collection of stored networks
+     */
+    List<Network> networks();
+
+    /**
+     * Returns a network.
+     *
+     * @param  networkId network id in URI format
+     * @return value of network
+     */
+    Network network(KeyId networkId);
+
+    /**
+     * Updates a network.
+     *
+     * @param network value of the network to be updated
+     */
+    void updateNetwork(Network network);
+
+    /**
+     * Removes a network.
+     *
+     * @param  networkId network id in URI format
+     */
+    void removeNetwork(KeyId networkId);
+
+    /**
+     * Returns a network link.
+     *
+     * @param linkKey link key
+     * @return value of network link
+     */
+    NetworkLink networkLink(NetworkLinkKey linkKey);
+
+    /**
+     * Updates a network link.
+     *
+     * @param linkKey link key
+     * @param link link object to be updated
+    */
+    void updateNetworkLink(NetworkLinkKey linkKey, NetworkLink link);
+
+    /**
+     * Removes a network link.
+     *
+     * @param linkKey link key
+     */
+    void removeNetworkLink(NetworkLinkKey linkKey);
+
+    /**
+     * Returns a network node.
+     *
+     * @param nodeKey node key
+     * @return value of network node
+     */
+    NetworkNode networkNode(NetworkNodeKey nodeKey);
+
+    /**
+     * Updates a network node.
+     *
+     * @param nodeKey node key
+     * @param node node object to be updated
+     */
+    void updateNetworkNode(NetworkNodeKey nodeKey, NetworkNode node);
+
+    /**
+     * Removes a network node.
+     *
+     * @param nodeKey node key
+     */
+    void removeNetworkNode(NetworkNodeKey nodeKey);
+
+    /**
+     * Updates a terminationPoint.
+     *
+     * @param terminationPointKey termination point id
+     * @param terminationPoint termination point object to be updated
+     */
+    void updateTerminationPoint(TerminationPointKey terminationPointKey,
+                                TerminationPoint terminationPoint);
+
+    /**
+     * Removes a terminationPoint.
+     *
+     * @param terminationPointKey termination point id
+     */
+    void removeTerminationPoint(TerminationPointKey terminationPointKey);
+
+    /**
+     * Returns a collection of currently known TE topologies.
+     *
+     * @return a collection of topologies
+     */
+    TeTopologies teTopologies();
+
+    /**
+     * Returns the TE Topology identified by its Id.
+     *
+     * @param  topologyId TE topology Key
+     * @return value of TeTopology
+     */
+    TeTopology teTopology(TeTopologyKey topologyId);
+
+    /**
+     * Creates or updates a TE topology.
+     *
+     * @param teTopology value of the TE topology to be updated
+     */
+    void updateTeTopology(TeTopology teTopology);
+
+    /**
+     * Removes the TE Topology identified by its Id.
+     *
+     * @param topologyId TE topology key
+     */
+    void removeTeTopology(TeTopologyKey topologyId);
+
+    /**
+     * Returns the TE node identified by its Id.
+     *
+     * @param  nodeId the te node key
+     * @return value of node
+     */
+    TeNode teNode(TeNodeKey nodeId);
+
+    /**
+     * Creates or updates a TE Node.
+     *
+     * @param nodeKey te node id
+     * @param node node object to be updated
+     */
+    void updateTeNode(TeNodeKey nodeKey, TeNode node);
+
+    /**
+     * Removes the TE node identified by its Id.
+     *
+     * @param  nodeId the te node key
+     */
+    void removeTeNode(TeNodeKey nodeId);
+
+    /**
+     * Returns the TE link identified by its Id.
+     *
+     * @param  linkId the te link key
+     * @return value of link
+     */
+    TeLink teLink(TeLinkTpGlobalKey linkId);
+
+    /**
+     * Creates or updates a TE Link.
+     *
+     * @param linkKey link id
+     * @param link teLink object to be updated
+     */
+    void updateTeLink(TeLinkTpGlobalKey linkKey, TeLink link);
+
+    /**
+     * Removes the TE link identified by its Id.
+     *
+     * @param  linkId the te link key
+     */
+    void removeTeLink(TeLinkTpGlobalKey linkId);
+
+    /**
+     * Returns a tunnel termination point identified by its id.
+     *
+     * @param  ttpId the tunnel termination point key
+     * @return the tunnel termination point
+     */
+    TunnelTerminationPoint tunnelTerminationPoint(TtpKey ttpId);
+
+    /**
+     * Returns the network Id for a TE Topology key.
+     *
+     * @param  teTopologyKey a TE topology key
+     * @return value of network Id
+     */
+    KeyId networkId(TeTopologyKey teTopologyKey);
+
+    /**
+     * Returns the network node key for a TE node key.
+     *
+     * @param  teNodeKey a TE node key
+     * @return value of network node key
+     */
+    NetworkNodeKey nodeKey(TeNodeKey teNodeKey);
+
+    /**
+     * Returns the network link key for a TE link key.
+     *
+     * @param  teLinkKey a TE node key
+     * @return value of network link key
+     */
+    NetworkLinkKey linkKey(TeLinkTpGlobalKey teLinkKey);
+
+    /**
+     * Returns the termination point key for a TE termination point key.
+     *
+     * @param  teTpKey a TE termination point key
+     * @return value of termination point key
+     */
+    TerminationPointKey terminationPointKey(TeLinkTpGlobalKey teTpKey);
+
+    /**
+     * Returns the long value of next available TE topology id.
+     *
+     * @return value of TE topology id
+     */
+    long nextTeTopologyId();
+
+    /**
+     * Returns the next available TE node Id in a TE topology.
+     *
+     * @param topologyKey TE topology key
+     * @return value of TE node id
+     */
+    long nextTeNodeId(TeTopologyKey topologyKey);
+
+    /**
+     * Sets the next available TE node Id in a TE topology.
+     *
+     * @param topologyKey TE topology key
+     * @param nextNodeId value of next TE node id
+     */
+    void setNextTeNodeId(TeTopologyKey topologyKey, long nextNodeId);
+
+    /**
+     * Sets the queue to store the events originating from consistent maps.
+     *
+     * @param queue a blocking queue
+     */
+    void setMapEventQueue(BlockingQueue<TeTopologyMapEvent> queue);
+
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyStoreDelegate.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyStoreDelegate.java
new file mode 100644
index 0000000..9b86164
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyStoreDelegate.java
@@ -0,0 +1,26 @@
+/*
+ * 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 org.onosproject.store.StoreDelegate;
+import org.onosproject.tetopology.management.api.TeTopologyEvent;
+
+/**
+ * Abstraction of TE networks store delegate.
+ */
+public interface TeTopologyStoreDelegate extends StoreDelegate<TeTopologyEvent> {
+
+}
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/package-info.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/package-info.java
new file mode 100644
index 0000000..89e3eee
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/package-info.java
@@ -0,0 +1,20 @@
+/**
+ * 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.
+ */
+
+/**
+ * TE Topology Management implementation.
+ */
+package org.onosproject.tetopology.management.impl;
