diff --git a/apps/tetopology/BUCK b/apps/tetopology/BUCK
index 9ccc662..e818418 100644
--- a/apps/tetopology/BUCK
+++ b/apps/tetopology/BUCK
@@ -3,6 +3,7 @@
 ]
 
 onos_app (
+    app_name = 'org.onosproject.tetopology',
     title = 'TE Topology Core App',
     category = 'ACTN',
     url = 'http://onosproject.org',
diff --git a/apps/tetopology/app/BUCK b/apps/tetopology/app/BUCK
new file mode 100644
index 0000000..61376a4
--- /dev/null
+++ b/apps/tetopology/app/BUCK
@@ -0,0 +1,17 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//apps/tetopology/api:onos-apps-tetopology-api',
+    '//incubator/api:onos-incubator-api',
+    '//core/store/serializers:onos-core-serializers',
+]
+
+TEST_DEPS = [
+    '//lib:TEST_ADAPTERS',
+    '//utils/osgi:onlab-osgi-tests',
+    '//incubator/api:onos-incubator-api-tests',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
+)
diff --git a/apps/tetopology/app/app.xml b/apps/tetopology/app/app.xml
new file mode 100644
index 0000000..e675d4c
--- /dev/null
+++ b/apps/tetopology/app/app.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015 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.
+  -->
+<app name="org.onosproject.tetopology" origin="HUAWEI" version="${project.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
+</app>
+
diff --git a/apps/tetopology/app/features.xml b/apps/tetopology/app/features.xml
new file mode 100644
index 0000000..b22a210
--- /dev/null
+++ b/apps/tetopology/app/features.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ Copyright 2015 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.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <feature name="${project.artifactId}" version="${project.version}"
+             description="${project.description}">
+        <feature>onos-api</feature>
+        <bundle>mvn:${project.groupId}/onos-app-tetopology-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-tetopology/${project.version}</bundle>
+    </feature>
+</features>
diff --git a/apps/tetopology/app/pom.xml b/apps/tetopology/app/pom.xml
new file mode 100644
index 0000000..0566e85
--- /dev/null
+++ b/apps/tetopology/app/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-tetopology</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>onos-app-tetopology</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <description>IETF TE topology application</description>
+
+    <dependencies>
+ 
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-tetopology-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+         <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava-testlib</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-osgi</artifactId>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <scope>test</scope>
+            <classifier>tests</classifier>
+        </dependency>
+         <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-common</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+ 
+    </dependencies>
+</project>
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;
diff --git a/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/DefaultBuilder.java b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/DefaultBuilder.java
new file mode 100644
index 0000000..564a938
--- /dev/null
+++ b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/DefaultBuilder.java
@@ -0,0 +1,330 @@
+/*
+ * 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;
+
+import java.util.BitSet;
+import java.util.List;
+import java.util.Map;
+
+import org.onlab.packet.Ip4Address;
+import org.onosproject.net.DeviceId;
+import org.onosproject.tetopology.management.api.DefaultNetwork;
+import org.onosproject.tetopology.management.api.EncodingType;
+import org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.Network;
+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.TeTopologyId;
+import org.onosproject.tetopology.management.api.TeTopologyKey;
+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.ExternalLink;
+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.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.UnderlayPath;
+import org.onosproject.tetopology.management.api.node.CommonNodeData;
+import org.onosproject.tetopology.management.api.node.ConnectivityMatrix;
+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.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.TunnelTerminationPoint;
+import org.onosproject.tetopology.management.impl.TeMgrUtil;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Builds a sample abstract TE Topology, which consists of one node(represents
+ * an entire network), one inter-domain link and one TTP.
+ */
+public final class DefaultBuilder {
+    private static final String NODEIP = "100.10.10.10";
+    // Bandwidth in GigaBits/second
+    private static final float[] ODU0BW = {1.25f, 1.25f, 1.25f, 1.25f, 1.25f, 1.25f, 1.25f, 1.25f};
+    private static final float[] ODU2BW = {10, 10, 10, 10, 10, 10, 10, 10};
+    private static final float[] ODU3BW = {40, 40, 40, 40, 40, 40, 40, 40};
+    private static final float[] ODU4BW = {100, 100, 100, 100, 100, 100, 100, 100};
+
+    private static final String ODU2 = "ODU2";
+    private static final String ODU3 = "ODU3";
+    private static final String ODU4 = "ODU4";
+
+    private static final long PROVIDER_ID = 0x100;
+    private static final long CLIENT_ID = 0x0a0a0a0a;
+    private static final long CLIENT_NIL = 0;
+    private static final long ABSTRACT_TOPOLOGY_ID = 100;
+    private static final long NATIVE_TOPOLOGY_ID = 1;
+    private static final long NUM_TPS = 1;
+    private static final long NUM_TTPS = 1;
+    private static final boolean ABSTRACT = true;
+    private static final boolean UNABSTRACT = false;
+    private static final int FIRST_INDEX = 0;
+    private static final long INTER_DOMAIN_LINK_PLUGID = 100;
+    private static final long LINK_COST = 500;
+    private static final long LINK_DELAY = 2000;
+    private static final long LINK_SRLG = 150;
+    private static final String DOMAIN_ID = "DomainX";
+
+    private static NetworkNode networkNode;
+    private static TeNode teNode;
+    private static NetworkLink networkLink;
+    private static TeLink teLink;
+    private static Network network;
+    private static TunnelTerminationPoint ttp;
+
+    private static TeTopologyKey teTopologyKey = new TeTopologyKey(PROVIDER_ID,
+                                                                   CLIENT_ID,
+                                                                   ABSTRACT_TOPOLOGY_ID);
+
+    // no instantiation
+    private DefaultBuilder() {
+    }
+
+    private static TunnelTerminationPoint ttpBuilder(long ttpId) {
+        return new DefaultTunnelTerminationPoint(ttpId, SwitchingType.OTN_TDM_CAPABLE,
+                                                 EncodingType.LSP_ENCODING_ODUK,
+                                                 new BitSet(TeConstants.FLAG_MAX_BITS),
+                                                 null, null,
+                                                 ODU2BW); //10G for ODU2
+    }
+
+    private static TerminationPoint tpBuilder(long teTpId) {
+        return new DefaultTerminationPoint(KeyId.keyId(Long.toString(teTpId)), null, teTpId);
+    }
+
+    private static NetworkNode nodeBuilder(String nodeIp, long numTps, long numTtps,
+                                          TeTopologyKey underlayTopologyId, TeNodeKey supportTeNodeId,
+                                          TeNodeKey sourceTeNodeId, boolean isAbstract) {
+        long teNodeId = Ip4Address.valueOf(nodeIp).toInt();
+        BitSet flags = new BitSet(TeConstants.FLAG_MAX_BITS);
+
+        if (isAbstract) {
+            flags.set(TeNode.BIT_ABSTRACT);
+        }
+        CommonNodeData common = new CommonNodeData(nodeIp, TeStatus.UP, TeStatus.UP, flags);
+        Map<Long, ConnectivityMatrix> connMatrices = null;
+        List<Long> teTpIds = Lists.newArrayList();
+        Map<KeyId, TerminationPoint> tps = Maps.newHashMap();
+        for (long i = 0; i < numTps; i++) {
+            teTpIds.add(i);
+            tps.put(KeyId.keyId(Long.toString(i)), tpBuilder(i));
+        }
+        //TTP
+        Map<Long, TunnelTerminationPoint> ttps = Maps.newHashMap();
+        for (long i = 0; i < numTtps; i++) {
+            ttps.put(i, ttpBuilder(i));
+        }
+        ttp = ttps.get(FIRST_INDEX);
+        //TeNode
+        teNode = new DefaultTeNode(teNodeId, underlayTopologyId,
+                                   supportTeNodeId, sourceTeNodeId,
+                                          common, connMatrices, teTpIds, ttps, teTpIds);
+        List<NetworkNodeKey> supportingNodeIds = null;
+        if (supportTeNodeId != null) {
+            supportingNodeIds = Lists
+                    .newArrayList(TeMgrUtil.networkNodeKey(supportTeNodeId));
+        }
+
+        return new DefaultNetworkNode(KeyId.keyId(nodeIp), supportingNodeIds, teNode, tps);
+    }
+
+    private static LinkBandwidth linkBwBuilder(String odu) {
+
+        float[] maxBandwidth;  //Maximum bandwidth, Size is MAX_PRIORITY + 1
+        float[] avaiBandwidth; //Unreserved bandwidth, Size is MAX_PRIORITY + 1
+        float[] maxAvialLspBandwidth;  //Maximum available bandwidth for a LSP
+        float[] minAvialLspBandwidth;  //Minimum available bandwidth for a LSP
+        short odu0s;
+        short odu1s;
+        short odu2s;
+        short odu2es = 0;
+        short odu3s;
+        short odu4s;
+        short oduFlexes = 0;
+
+        switch (odu) {
+        case ODU3:
+            maxBandwidth = ODU3BW;
+            avaiBandwidth = ODU3BW;
+            maxAvialLspBandwidth = ODU3BW;
+            minAvialLspBandwidth = ODU0BW;
+            odu0s = 32;
+            odu1s = 16;
+            odu2s = 4;
+            odu3s = 1;
+            odu4s = 0;
+            break;
+        case ODU4:
+            maxBandwidth = ODU4BW;
+            avaiBandwidth = ODU4BW;
+            maxAvialLspBandwidth = ODU4BW;
+            minAvialLspBandwidth = ODU0BW;
+            odu0s = 80;
+            odu1s = 40;
+            odu2s = 10;
+            odu3s = 2;
+            odu4s = 1;
+            break;
+        default:
+            maxBandwidth = ODU2BW;
+            avaiBandwidth = ODU2BW;
+            maxAvialLspBandwidth = ODU2BW;
+            minAvialLspBandwidth = ODU0BW;
+            odu0s = 8;
+            odu1s = 4;
+            odu2s = 1;
+            odu3s = 0;
+            odu4s = 0;
+        }
+
+        OduResource oduRrc = new OduResource(odu0s, odu1s, odu2s, odu2es, odu3s,
+                                             odu4s, oduFlexes);
+        return new LinkBandwidth(maxBandwidth, avaiBandwidth, maxAvialLspBandwidth,
+                                 minAvialLspBandwidth, oduRrc);
+    }
+
+    private static NetworkLink linkBuilder(TeLinkTpKey teLinkKey, TeLinkTpKey peerTeLinkKey,
+                                          TeTopologyKey underlayTopologyId, TeLinkTpGlobalKey supportTeLinkId,
+                                          TeLinkTpGlobalKey sourceTeLinkId, boolean isAbstract, Long plugid,
+                                          Long cost, Long delay, List<Long> srlgs, String odu) {
+        //NetworkLink
+        KeyId linkId = TeMgrUtil.toNetworkLinkId(teLinkKey);
+        NodeTpKey source = new NodeTpKey(KeyId.keyId(Long.toString(teLinkKey.teNodeId())),
+                                         KeyId.keyId(Long.toString(teLinkKey.teLinkTpId())));
+        NodeTpKey destination = null;
+        if (peerTeLinkKey != null) {
+            destination = new NodeTpKey(KeyId.keyId(Long.toString(peerTeLinkKey.teNodeId())),
+                                        KeyId.keyId(Long.toString(peerTeLinkKey.teLinkTpId())));
+        }
+        List<NetworkLinkKey> supportingLinkIds = null;
+        if (supportTeLinkId != null) {
+            supportingLinkIds = Lists
+                    .newArrayList(TeMgrUtil.networkLinkKey(supportTeLinkId));
+        }
+        BitSet flags = new BitSet(TeConstants.FLAG_MAX_BITS);
+        if (isAbstract) {
+            flags.set(TeLink.BIT_ABSTRACT);
+        }
+        ExternalLink externalLink = null;
+
+        if (plugid != null) {
+            // Inter-Domain Link
+            flags.set(TeLink.BIT_ACCESS_INTERDOMAIN);
+            externalLink = new ExternalLink(null, plugid);
+        }
+        UnderlayPath underlayPath = null;
+        Long adminGroup = null;
+        List<Long> interLayerLocks = null;
+        teLink = new DefaultTeLink(teLinkKey, peerTeLinkKey, underlayTopologyId,
+                                          supportTeLinkId, sourceTeLinkId,
+                                          new CommonLinkData(TeStatus.UP, TeStatus.UP, flags,
+                                                             SwitchingType.OTN_TDM_CAPABLE,
+                                                             EncodingType.LSP_ENCODING_ODUK,
+                                                             externalLink, underlayPath,
+                                                             new TePathAttributes(cost, delay, srlgs),
+                                                             adminGroup, interLayerLocks, linkBwBuilder(odu)));
+        return new DefaultNetworkLink(linkId, source, destination, supportingLinkIds, teLink);
+    }
+
+    private static Network networkBuilder(TeTopologyId teTopologyId, KeyId supportingNetworkId,
+                                         Map<KeyId, NetworkNode> nodes, Map<KeyId, NetworkLink> links,
+                                         boolean serverProvided, DeviceId ownerId) {
+        KeyId networkId = TeMgrUtil.toNetworkId(teTopologyId);
+        List<KeyId> supportingNetworkIds = null;
+        if (supportingNetworkId != null) {
+            supportingNetworkIds = Lists.newArrayList(supportingNetworkId);
+        }
+        return new DefaultNetwork(networkId, supportingNetworkIds, nodes, links, teTopologyId,
+                              serverProvided, ownerId);
+    }
+
+    /**
+     * Returns the key for the sample TE Topology.
+     *
+     * @return value of TE Topology key
+     */
+    public static TeTopologyKey teTopologyKey() {
+        return teTopologyKey;
+    }
+
+    /**
+     * Returns the abstract TE Node in the sample TE Topology.
+     *
+     * @return value of TE node
+     */
+    public static TeNode teNode() {
+        return teNode;
+    }
+
+    /**
+     * Returns the TE link in the sample TE Topology.
+     *
+     * @return value of TE link
+     */
+    public static TeLink teLink() {
+        return teLink;
+    }
+
+    /**
+     * Builds a sample abstract TE Topology, which consists of one abstract node
+     * representing an entire physical network, one inter-domain link and one
+     * TTP.
+     *
+     * @return value of network with an abstract TE Topology
+     */
+    public static Network buildSampleAbstractNetwork() {
+        TeTopologyKey underlayTopologyId = new TeTopologyKey(PROVIDER_ID,
+                                                             CLIENT_NIL,
+                                                             NATIVE_TOPOLOGY_ID);
+        Map<KeyId, NetworkNode> nodes = Maps.newHashMap();
+        networkNode = nodeBuilder(NODEIP, NUM_TPS, NUM_TTPS, underlayTopologyId,
+                                  null, null, ABSTRACT);
+        nodes.put(networkNode.nodeId(), networkNode);
+
+        Map<KeyId, NetworkLink> links = Maps.newHashMap();
+        TeLinkTpKey node1tp1 = new TeLinkTpKey(networkNode.teNode().teNodeId(),
+                                               networkNode.teNode()
+                                                       .teTerminationPointIds()
+                                                       .get(FIRST_INDEX));
+        networkLink = linkBuilder(node1tp1, null, null, null, null, UNABSTRACT,
+                                  INTER_DOMAIN_LINK_PLUGID, LINK_COST,
+                                  LINK_DELAY, Lists.newArrayList(LINK_SRLG),
+                                  ODU4);
+        links.put(networkLink.linkId(), networkLink);
+        DeviceId ownerId = DeviceId.deviceId(DOMAIN_ID);
+        TeTopologyId topologyId = new TeTopologyId(PROVIDER_ID, CLIENT_ID, Long
+                .toString(ABSTRACT_TOPOLOGY_ID));
+        network = networkBuilder(topologyId, null, nodes, links, false,
+                                 ownerId);
+        return network;
+    }
+
+}
diff --git a/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/SimpleTeTopologyStore.java b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/SimpleTeTopologyStore.java
new file mode 100644
index 0000000..3abaddc
--- /dev/null
+++ b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/SimpleTeTopologyStore.java
@@ -0,0 +1,1033 @@
+/**
+ * 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;
+
+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.TE_TOPOLOGY_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_REMOVED;
+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.Service;
+import org.onosproject.net.DeviceId;
+import org.onosproject.store.AbstractStore;
+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.KeyId;
+import org.onosproject.tetopology.management.api.Network;
+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.TeTopologyId;
+import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetopology.management.api.TeUtils;
+import org.onosproject.tetopology.management.api.link.DefaultNetworkLink;
+import org.onosproject.tetopology.management.api.link.DefaultTeLink;
+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.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.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.onosproject.tetopology.management.impl.InternalNetwork;
+import org.onosproject.tetopology.management.impl.InternalNetworkLink;
+import org.onosproject.tetopology.management.impl.InternalNetworkNode;
+import org.onosproject.tetopology.management.impl.InternalTeLink;
+import org.onosproject.tetopology.management.impl.InternalTeNode;
+import org.onosproject.tetopology.management.impl.InternalTeTopology;
+import org.onosproject.tetopology.management.impl.InternalTerminationPoint;
+import org.onosproject.tetopology.management.impl.TeMgrUtil;
+import org.onosproject.tetopology.management.impl.TeTopologyManager;
+import org.onosproject.tetopology.management.impl.TeTopologyMapEvent;
+import org.onosproject.tetopology.management.impl.TeTopologyStore;
+import org.onosproject.tetopology.management.impl.TeTopologyStoreDelegate;
+import org.slf4j.Logger;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Implementation of the TE network store.
+ */
+@Component(immediate = true)
+@Service
+public class SimpleTeTopologyStore
+        extends AbstractStore<TeTopologyEvent, TeTopologyStoreDelegate>
+        implements TeTopologyStore {
+    private static final String STORE_NAME = "TE_NETWORK_TOPOLOGY_STORE";
+    private final Logger log = getLogger(getClass());
+
+    // Track TE topologies by TE Topology key
+    private Map<TeTopologyKey, InternalTeTopology> teTopologyMap = Maps
+            .newConcurrentMap();
+    // Track networks by network Id
+    private Map<KeyId, InternalNetwork> networkMap = Maps.newConcurrentMap();
+    // Track TE nodes by TE node key
+    private Map<TeNodeKey, InternalTeNode> teNodeMap = Maps.newConcurrentMap();
+    // Track ConnectivityMatrix by its key
+    private Map<ConnectivityMatrixKey, ConnectivityMatrix> connMatrixMap = Maps
+            .newConcurrentMap();
+    // Track Tunnel Termination Points by its key
+    private Map<TtpKey, TunnelTerminationPoint> ttpMap = Maps
+            .newConcurrentMap();
+    // Track network nodes by network node key
+    private Map<NetworkNodeKey, InternalNetworkNode> networkNodeMap = Maps
+            .newConcurrentMap();
+    // Track TE links by its key
+    private Map<TeLinkTpGlobalKey, InternalTeLink> teLinkMap = Maps
+            .newConcurrentMap();
+    // Track network links by network link key
+    private Map<NetworkLinkKey, InternalNetworkLink> networkLinkMap = Maps
+            .newConcurrentMap();
+    // Track Termination points by termination point key
+    private Map<TerminationPointKey, InternalTerminationPoint> tpMap = Maps
+            .newConcurrentMap();
+    // Track termination point keys by TE termination point Key
+    private Map<TeLinkTpGlobalKey, TerminationPointKey> tpKeyMap = Maps
+            .newConcurrentMap();
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        teTopologyMap.clear();
+        networkMap.clear();
+        teNodeMap.clear();
+        connMatrixMap.clear();
+        networkNodeMap.clear();
+        teLinkMap.clear();
+        networkLinkMap.clear();
+        tpMap.clear();
+        tpKeyMap.clear();
+        ttpMap.clear();
+        log.info("Stopped");
+    }
+
+    @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());
+        if (curTopology != null) {
+            // Existing topology update
+            // Remove existing map entries first, which should be removed by
+            // its own events
+            removeTopologyeMapEntrys(curTopology);
+        }
+        // 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
+                && teTopology(curNetwork.teTopologyKey()) != null) {
+            topologyId = new TeTopologyId(curNetwork.teTopologyKey()
+                    .providerId(), curNetwork.teTopologyKey().clientId(),
+                                          teTopology(curNetwork.teTopologyKey())
+                                                  .teTopologyIdStringValue());
+            ownerId = teTopology(curNetwork.teTopologyKey()).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());
+        if (curNetwork != null) {
+            // Existing topology update
+            // Remove existing map entries first,
+            removeNetworkMapEntrys(curNetwork, false);
+        }
+        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);
+            // Assume new topology
+            TeTopologyEvent topologyEvent = new TeTopologyEvent(TE_TOPOLOGY_ADDED,
+                                                                teTopology(topoKey));
+            notifyDelegate(topologyEvent);
+        }
+        // Finally Update networkMap
+        InternalNetwork newNetwork = new InternalNetwork(network);
+        newNetwork.setTeTopologyKey(topoKey);
+        networkMap.put(network.networkId(), newNetwork);
+        // Assume new network
+        TeTopologyEvent topologyEvent = new TeTopologyEvent(NETWORK_ADDED,
+                                                            network(network
+                                                                    .networkId()));
+        notifyDelegate(topologyEvent);
+    }
+
+    @Override
+    public void removeNetwork(KeyId networkId) {
+        // Remove it from networkMap
+        InternalNetwork network = networkMap.remove(networkId);
+        TeTopologyEvent topologyEvent = new TeTopologyEvent(NETWORK_REMOVED,
+                                                            new DefaultNetwork(networkId,
+                                                                               null,
+                                                                               null,
+                                                                               null,
+                                                                               null,
+                                                                               false,
+                                                                               null));
+        notifyDelegate(topologyEvent);
+        if (network != null && network.teTopologyKey() != null) {
+            removeNetworkMapEntrys(network, false);
+            teTopologyMap.remove(network.teTopologyKey());
+            topologyEvent = new TeTopologyEvent(TE_TOPOLOGY_REMOVED,
+                                                new DefaultTeTopology(network
+                                                        .teTopologyKey(), null, null, null, null));
+            notifyDelegate(topologyEvent);
+        }
+    }
+
+    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 TE Termination Points
+
+        // 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 0;
+    }
+
+    @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) {
+    }
+}
+
diff --git a/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/TeTopologyManagerTest.java b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/TeTopologyManagerTest.java
new file mode 100644
index 0000000..03d21fb
--- /dev/null
+++ b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/TeTopologyManagerTest.java
@@ -0,0 +1,182 @@
+/**
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.NetTestTools.injectEventDispatcher;
+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.TE_TOPOLOGY_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_REMOVED;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.event.Event;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.tetopology.management.api.Network;
+import org.onosproject.tetopology.management.api.TeTopology;
+import org.onosproject.tetopology.management.api.TeTopologyEvent;
+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.TeLink;
+import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
+import org.onosproject.tetopology.management.api.node.TeNode;
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+import org.onosproject.tetopology.management.impl.TeMgrUtil;
+import org.onosproject.tetopology.management.impl.TeTopologyManager;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Test TeTopology service and TeTopologyProvider service.
+ */
+public class TeTopologyManagerTest {
+    private static final ProviderId PID = new ProviderId("test", "TeTopologyManagerTest");
+
+    private TeTopologyManager mgr;
+    protected TeTopologyService service;
+    protected TeTopologyProviderRegistry registry;
+    protected TeTopologyProviderService providerService;
+    protected TestProvider provider;
+    protected TestListener listener = new TestListener();
+
+    @Before
+    public void setUp() {
+        mgr = new TeTopologyManager();
+        service = mgr;
+        registry = mgr;
+        mgr.store = new SimpleTeTopologyStore();
+
+        injectEventDispatcher(mgr, new TestEventDispatcher());
+
+        mgr.activateBasics();
+        service.addListener(listener);
+
+        provider = new TestProvider();
+        providerService = registry.register(provider);
+        assertTrue("providerService should not be null", providerService != null);
+        assertTrue("Provider should be registered",
+                   registry.getProviders().contains(provider.id()));
+    }
+
+    @After
+    public void tearDown() {
+        registry.unregister(provider);
+        assertFalse("provider should not be registered",
+                    registry.getProviders().contains(provider.id()));
+        service.removeListener(listener);
+        mgr.deactivateBasics();
+    }
+
+    private void createNetwork() {
+        Network originNetwork = DefaultBuilder.buildSampleAbstractNetwork();
+        providerService.networkUpdated(originNetwork);
+        Network network = service
+                .network(TeMgrUtil.toNetworkId(DefaultBuilder.teTopologyKey()));
+        assertNotNull("Network should be found", network);
+    }
+
+    /**
+     * Checks the right events are received when a network with TE topology is
+     * added.
+     */
+    @Test
+    public void networkAdded() {
+        createNetwork();
+        validateEvents(TE_TOPOLOGY_ADDED, NETWORK_ADDED);
+    }
+
+    /**
+     * Checks the TE topology components are set properly in Manager and Store
+     * when a network is added.
+     */
+    @Test
+    public void teTopologyVerify() {
+        createNetwork();
+        TeTopology teTopology = service
+                .teTopology(DefaultBuilder.teTopologyKey());
+        assertNotNull("TeTopology should be found", teTopology);
+        assertTrue("Number of TE nodes should be 1",
+                   teTopology.teNodes().size() == 1);
+        assertTrue("Number of TE links should be 1",
+                   teTopology.teLinks().size() == 1);
+        TeNode teNode = service
+                .teNode(new TeNodeKey(DefaultBuilder.teTopologyKey(),
+                                      DefaultBuilder.teNode().teNodeId()));
+        assertNotNull("TeNode should be found", teNode);
+        assertTrue("Number of TTPs should be 1",
+                   teNode.tunnelTerminationPoints().size() == 1);
+        TeLink teLink = service
+                .teLink(new TeLinkTpGlobalKey(DefaultBuilder
+                        .teTopologyKey(), DefaultBuilder.teLink().teLinkKey()));
+        assertNotNull("TeLink should be found", teLink);
+    }
+
+    /**
+     * Checks the right events are received when a network with TE topology is
+     * added and then removed.
+     */
+    @Test
+    public void networkRemoved() {
+        createNetwork();
+        providerService.networkRemoved(TeMgrUtil
+                .toNetworkId(DefaultBuilder.teTopologyKey()));
+        validateEvents(TE_TOPOLOGY_ADDED, NETWORK_ADDED, NETWORK_REMOVED,
+                       TE_TOPOLOGY_REMOVED);
+    }
+
+    /**
+     * Validates whether the manager receives the right events.
+     *
+     * @param types a set of types of control message event
+     */
+    protected void validateEvents(Enum... types) {
+        int i = 0;
+        assertEquals("wrong events received", types.length, listener.events.size());
+        for (Event event : listener.events) {
+            assertEquals("incorrect event type", types[i], event.type());
+            i++;
+        }
+        listener.events.clear();
+    }
+
+    private class TestProvider extends AbstractProvider implements TeTopologyProvider {
+        protected TestProvider() {
+            super(PID);
+        }
+    }
+
+    private static class TestListener implements TeTopologyListener {
+        final List<TeTopologyEvent> events = Lists.newArrayList();
+
+        @Override
+        public void event(TeTopologyEvent event) {
+            events.add(event);
+        }
+    }
+
+}
diff --git a/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/package-info.java b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/package-info.java
new file mode 100644
index 0000000..071f1d2
--- /dev/null
+++ b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/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.
+ */
+
+/**
+ * The TE topology implementation test functions.
+ */
+package org.onosproject.tetopology.management;
diff --git a/apps/tetopology/pom.xml b/apps/tetopology/pom.xml
index fcf01a7..1e01d84 100644
--- a/apps/tetopology/pom.xml
+++ b/apps/tetopology/pom.xml
@@ -31,9 +31,7 @@
 
     <modules>
         <module>api</module>
-        <!--
         <module>app</module>
-        -->
     </modules>
 
 <!--
