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;
