diff --git a/src/lib/profiles/data-management/Current/WdmDictionary.h b/src/lib/profiles/data-management/Current/WdmDictionary.h
new file mode 100644
index 0000000..5685465
--- /dev/null
+++ b/src/lib/profiles/data-management/Current/WdmDictionary.h
@@ -0,0 +1,230 @@
+/*
+ *
+ *    Copyright (c) 2018 Google LLC.
+ *    Copyright (c) 2013-2017 Nest Labs, Inc.
+ *    All rights reserved.
+ *
+ *    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.
+ */
+
+/**
+ *    @file
+ *      This file provides a more logical container representation of a WDM dictionary
+ *      that permits both indexing against the dictionary key as well as a more logical primary
+ *      key
+ */
+
+#ifndef _WEAVE_DATA_MANAGEMENT_WDM_DICTIONARY_H
+#define _WEAVE_DATA_MANAGEMENT_WDM_DICTIONARY_H
+
+#include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h>
+
+#include <Weave/Core/WeaveCore.h>
+#include <Weave/Core/WeaveMessageLayer.h>
+#include <Weave/Profiles/ProfileCommon.h>
+#include <Weave/Support/CodeUtils.h>
+#include <Weave/Profiles/data-management/MessageDef.h>
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+
+using namespace boost::multi_index;
+
+namespace nl {
+namespace Weave {
+namespace Profiles {
+namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) {
+
+//
+// This templated class provides a more user-friendly type when interacting with WDL maps.
+// WDL maps are constrained in their keys to having 16-bit numerical keys. As such, these maps
+// cannot be thought of as traditional maps that have the key being the logical/primary key used to 
+// index the data in the collection. Rather, the key is merely a unique number assigned to each item,
+// lacking any semantic or logical meaning. The actual logical key is embedded in the item itself, and
+// be any WDL type. In this sense, WDL maps can be thought of as spare arrays.
+//
+// Applications will typically want to interact with the collection locally on devices more naturally as a keyed collection, 
+// with the data index using the logical key. This requires them to maintain a two-map solution: 
+// one to store the original data in the trait, and another to translate from the logical key to the map key.
+//
+// This templated class utilizes boost's multi_index_container, which permits indexing the data against multiple keys
+// while still retaining efficient storage and look-up of the data. The class wraps the provided boost type and
+// provides helper methods to interact with each key's sub-table. 
+//
+// Specializing the template requires passing in both the logical key type as well as the value type as well.
+//
+// Requirements on the types include:
+//      Logical Key Type: Has both '<' and '==' operators implemented.
+//      Value Type: Has the '==' operator implemented.
+//
+// The class also provides methods to compare against another instance of the collection to easily figure out the
+// set of items added, removed or modified against the logical key. This allows for comparisons
+//
+template <class KeyT, class ValueT>
+class WdmDictionary {
+public:
+    //
+    // This is the Item that is used in the collection, housing both the 16-bit dictionary
+    // key as well as the logical KeyT typed key.
+    // It also contains the value as well.
+    //
+    struct Item {
+        Item(uint16_t dictKey) { _dict_key = dictKey; _logical_key = 0; }
+        Item() { _dict_key = 0; _logical_key = 0; }
+
+        bool operator<(const Item& i1) const {
+            return (_logical_key < i1._logical_key);
+        }
+
+        bool operator ==(const Item& i) const {
+            return (_logical_key == i._logical_key && _dict_key == i._dict_key && _data == i._data);
+        }
+
+        ValueT _data;
+        uint16_t _dict_key;
+        KeyT _logical_key;
+    };
+
+    struct map_key{};
+    struct logical_key{};
+
+    typedef multi_index_container<
+        Item,
+        indexed_by<
+            // Both indexes are of type 'ordered_unique' since it's expected there will and should
+            // not be collisions in either of the key-spaces.
+            ordered_unique<tag<map_key>, member<Item, uint16_t, &Item::_dict_key> >,
+            ordered_unique<tag<logical_key>, member<Item, KeyT, &Item::_logical_key> >
+        >
+    > Container;
+
+    typedef typename Container::template index<map_key>::type DictKeyTableType;
+    typedef typename Container::template index<map_key>::type::iterator DictKeyTableTypeIterator;
+    typedef typename Container::template index<logical_key>::type LogicalKeyTableType;
+    typedef typename Container::template index<logical_key>::type::iterator LogicalKeyTableTypeIterator;
+
+    DictKeyTableType& GetDictKeyTable() { return _container.template get<map_key>(); }
+    LogicalKeyTableType& GetLogicalKeyTable() {  return _container.template get<logical_key>(); }
+
+    // 
+    // This is a convenience method that automatically creates an element in the collection with a particular
+    // dictionary key, or accesses an existing element that already exists, and allows the caller to mutate a member
+    // through a provided closure.
+    //
+    void ModifyItem(uint16_t dictKey, std::function<void(Item&)> func);
+   
+    //
+    // The following methods compare against a provided container and enumerates items that have been added, deleted or modified.
+    // This is specifically done against the logical key table and *not* against the dictionary keys. This is necessary since certain
+    // implementations of dictionaries (like the Nest cloud service) do not provide key stability for the dictionary keys, occasionally
+    // re-key'ing them while retaining the logical key + value content.
+    //
+    void ItemsAdded(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&)> func, bool updateStore=false);
+    void ItemsRemoved(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&)> func, bool updateStore=false);
+    void ItemsModified(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&, LogicalKeyTableTypeIterator&)> func, bool updateStore=false);
+    bool IsEqual(WdmDictionary &dictionary);
+
+private: 
+    Container _container;
+};
+
+template <typename KeyT, typename ValueT>
+bool WdmDictionary<KeyT, ValueT>::IsEqual(WdmDictionary &dictionary)
+{
+    return (dictionary._container.size() == _container.size()) 
+        && std::equal(_container.begin(), _container.end(), dictionary._container.begin());
+}
+
+template <typename KeyT, typename ValueT>
+void WdmDictionary<KeyT, ValueT>::ModifyItem(uint16_t dictKey, std::function<void(Item &)> func)
+{
+    Item item = Item(dictKey);
+    DictKeyTableType& mapkey_tbl = _container.template get<map_key>();
+    mapkey_tbl.modify(mapkey_tbl.insert(item).first, [&func](Item &d) {
+        func(d);
+    });
+}
+
+template <typename KeyT, typename ValueT>
+void WdmDictionary<KeyT, ValueT>::ItemsAdded(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&)> func, bool updateStore)
+{
+    Container addedItems;
+    LogicalKeyTableType &addedItemsLogicalTbl = addedItems.template get<logical_key>();
+
+    std::set_difference(stagedContainer.GetLogicalKeyTable().begin(), stagedContainer.GetLogicalKeyTable().end(), 
+                        GetLogicalKeyTable().begin(), GetLogicalKeyTable().end(),
+                        std::inserter(addedItemsLogicalTbl, addedItemsLogicalTbl.begin()));
+
+    for (auto it = addedItemsLogicalTbl.begin(); it != addedItemsLogicalTbl.end(); it++) {
+        func(it);
+
+        if (updateStore) {
+            GetLogicalKeyTable().insert(*it);
+        }
+    }
+}
+
+template <typename KeyT, typename ValueT>
+void WdmDictionary<KeyT, ValueT>::ItemsRemoved(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&)> func, bool updateStore)
+{
+    Container removedItems;
+    LogicalKeyTableType &removedItemsLogicalTbl = removedItems.template get<logical_key>();
+
+    std::set_difference(GetLogicalKeyTable().begin(), GetLogicalKeyTable().end(),
+                        stagedContainer.GetLogicalKeyTable().begin(), stagedContainer.GetLogicalKeyTable().end(), 
+                        std::inserter(removedItemsLogicalTbl, removedItemsLogicalTbl.begin()));
+
+    for (auto it = removedItemsLogicalTbl.begin(); it != removedItemsLogicalTbl.end(); it++) {
+        func(it);
+
+        if (updateStore) {
+            GetLogicalKeyTable().erase(it->_logical_key);
+        }
+    }
+}
+
+template <typename KeyT, typename ValueT>
+void WdmDictionary<KeyT, ValueT>::ItemsModified(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&, LogicalKeyTableTypeIterator&)> func, bool updateStore)
+{
+    Container modifiedItems;
+    LogicalKeyTableType &modifiedItemsTbl = modifiedItems.template get<logical_key>();
+
+    std::set_intersection(stagedContainer.GetLogicalKeyTable().begin(), stagedContainer.GetLogicalKeyTable().end(), 
+                        GetLogicalKeyTable().begin(), GetLogicalKeyTable().end(),
+                        std::inserter(modifiedItemsTbl, modifiedItemsTbl.begin()));
+
+    for (auto it = modifiedItemsTbl.begin(); it != modifiedItemsTbl.end(); it++) {
+        auto it1 = GetLogicalKeyTable().find(it->_logical_key);
+        auto it2 = stagedContainer.GetLogicalKeyTable().find(it->_logical_key);
+
+        if (!(it1->_data == it2->_data)) {
+            func(it1, it2);
+        }
+
+        if (updateStore) {
+            GetLogicalKeyTable().modify(it1, [it2](auto &d) {
+                d = *it2;
+            });
+        }
+    }
+}
+
+}; // namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current)
+}; // namespace Profiles
+}; // namespace Weave
+}; // namespace nl
+
+#endif
diff --git a/src/test-apps/Makefile.am b/src/test-apps/Makefile.am
index 801e077..f1a7719 100644
--- a/src/test-apps/Makefile.am
+++ b/src/test-apps/Makefile.am
@@ -356,11 +356,13 @@
 if HAVE_CXX11
 check_PROGRAMS +=                                \
     TestTDM                                      \
+    TestTDMDictionary                            \
     $(NULL)
 endif
 
 check_PROGRAMS +=                                \
     TestTDM                                      \
+	TestTDMDictionary							 \
     TestPathStore                                \
     TestWdmUpdateEncoder                         \
     TestWdmUpdateResponse                        \
@@ -469,6 +471,7 @@
 if HAVE_CXX11
 local_test_programs                           += \
     TestTDM                                      \
+    TestTDMDictionary                            \
     TestWDM                                      \
     $(NULL)
 endif
@@ -1220,6 +1223,20 @@
 TestTDM_CPPFLAGS                         = $(AM_CPPFLAGS) -I$(top_srcdir)/src/test-apps/schema
 TestTDM_LDFLAGS                          = $(AM_CPPFLAGS)
 TestTDM_LDADD                            = libWeaveTestCommon.a $(COMMON_LDADD)
+
+TestTDMDictionary_SOURCES                = TestTDMDictionary.cpp \
+                                           schema/nest/test/trait/TestHTrait.cpp \
+                                           schema/nest/test/trait/TestCTrait.cpp \
+                                           schema/nest/test/trait/TestBTrait.cpp \
+                                           schema/nest/test/trait/TestMismatchedCTrait.cpp \
+                                           schema/nest/test/trait/TestCommon.cpp \
+                                           MockMismatchedSchemaSinkAndSource.cpp \
+                                           TestPersistedStorageImplementation.cpp \
+                                           MockTestBTrait.cpp
+
+TestTDMDictionary_CPPFLAGS              = $(AM_CPPFLAGS) -I$(top_srcdir)/src/test-apps/schema
+TestTDMDictionary_LDFLAGS               = $(AM_CPPFLAGS)
+TestTDMDictionary_LDADD                 = libWeaveTestCommon.a $(COMMON_LDADD)
 endif
 
 TestWDM_SOURCES                          = TestWdm.cpp
diff --git a/src/test-apps/TestTDM.cpp b/src/test-apps/TestTDM.cpp
index fd00d05..0170916 100644
--- a/src/test-apps/TestTDM.cpp
+++ b/src/test-apps/TestTDM.cpp
@@ -65,6 +65,116 @@
 using namespace nl::Weave::TLV;
 using namespace nl::Weave::Profiles::DataManagement;
 
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+
+using namespace boost::multi_index;
+
+template <class KeyT, class ValueT>
+class WdmDictionary {
+public:
+    struct Item {
+        Item(uint16_t dictKey) { _dict_key = dictKey; }
+
+        bool operator<(const Item& i1) const {
+            return (_logical_key < i1._logical_key);
+        }
+
+        ValueT _data;
+        uint16_t _dict_key;
+        KeyT _logical_key;
+    };
+
+    struct map_key{};
+    struct logical_key{};
+
+    typedef multi_index_container<
+        Item,
+        indexed_by<
+            ordered_unique<tag<map_key>, member<Item, uint16_t, &Item::_dict_key> >,
+            ordered_unique<tag<logical_key>, member<Item, KeyT, &Item::_logical_key> >
+        >
+    > Container;
+
+    typedef typename Container::template index<map_key>::type DictKeyTableType;
+    typedef typename Container::template index<logical_key>::type LogicalKeyTableType;
+    typedef typename Container::template index<logical_key>::type::iterator LogicalKeyTableTypeIterator;
+
+    void ModifyItem(uint16_t dictKey, std::function<void(Item&)> func);
+    DictKeyTableType& GetDictKeyTable() { return _container.template get<map_key>(); }
+    LogicalKeyTableType& GetLogicalKeyTable() {  return _container.template get<logical_key>(); }
+
+    void ItemsAdded(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&)> func);
+    void ItemsRemoved(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&)> func);
+    void ItemsModified(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&, LogicalKeyTableTypeIterator&)> func);
+
+private: 
+    Container _container;
+};
+
+template <typename KeyT, typename ValueT>
+void WdmDictionary<KeyT, ValueT>::ModifyItem(uint16_t dictKey, std::function<void(Item &)> func)
+{
+    Item item = Item(dictKey);
+    DictKeyTableType& mapkey_tbl = _container.template get<map_key>();
+    mapkey_tbl.modify(mapkey_tbl.insert(item).first, [&func](Item &d) {
+        func(d);
+    });
+}
+
+template <typename KeyT, typename ValueT>
+void WdmDictionary<KeyT, ValueT>::ItemsAdded(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&)> func)
+{
+    Container addedItems;
+    LogicalKeyTableType &addedItemsLogicalTbl = addedItems.template get<logical_key>();
+
+    std::set_difference(stagedContainer.GetLogicalKeyTable().begin(), stagedContainer.GetLogicalKeyTable().end(), 
+                        GetLogicalKeyTable().begin(), GetLogicalKeyTable().end(),
+                        std::inserter(addedItemsLogicalTbl, addedItemsLogicalTbl.begin()));
+
+    for (auto it = addedItemsLogicalTbl.begin(); it != addedItemsLogicalTbl.end(); it++) {
+        func(it);
+    }
+}
+
+template <typename KeyT, typename ValueT>
+void WdmDictionary<KeyT, ValueT>::ItemsRemoved(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&)> func)
+{
+    Container removedItems;
+    LogicalKeyTableType &removedItemsLogicalTbl = removedItems.template get<logical_key>();
+
+    std::set_difference(GetLogicalKeyTable().begin(), GetLogicalKeyTable().end(),
+                        stagedContainer.GetLogicalKeyTable().begin(), stagedContainer.GetLogicalKeyTable().end(), 
+                        std::inserter(removedItemsLogicalTbl, removedItemsLogicalTbl.begin()));
+
+    for (auto it = removedItemsLogicalTbl.begin(); it != removedItemsLogicalTbl.end(); it++) {
+        func(it);
+    }
+}
+
+template <typename KeyT, typename ValueT>
+void WdmDictionary<KeyT, ValueT>::ItemsModified(WdmDictionary& stagedContainer, std::function<void(LogicalKeyTableTypeIterator&, LogicalKeyTableTypeIterator&)> func)
+{
+    Container modifiedItems;
+    LogicalKeyTableType &modifiedItemsTbl = modifiedItems.template get<logical_key>();
+
+    std::set_intersection(stagedContainer.GetLogicalKeyTable().begin(), stagedContainer.GetLogicalKeyTable().end(), 
+                        GetLogicalKeyTable().begin(), GetLogicalKeyTable().end(),
+                        std::inserter(modifiedItemsTbl, modifiedItemsTbl.begin()));
+
+    for (auto it = modifiedItemsTbl.begin(); it != modifiedItemsTbl.end(); it++) {
+        auto it1 = GetLogicalKeyTable().find(it->_logical_key);
+        auto it2 = stagedContainer.GetLogicalKeyTable().find(it->_logical_key);
+
+        if (!(it1->_data == it2->_data)) {
+            func(it1, it2);
+        }
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //
 // System/Platform definitions
diff --git a/src/test-apps/TestTDMDictionary.cpp b/src/test-apps/TestTDMDictionary.cpp
new file mode 100644
index 0000000..ccf0e85
--- /dev/null
+++ b/src/test-apps/TestTDMDictionary.cpp
@@ -0,0 +1,765 @@
+/*
+ *
+ *    Copyright (c) 2018 Google LLC.
+ *    Copyright (c) 2013-2017 Nest Labs, Inc.
+ *    All rights reserved.
+ *
+ *    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.
+ */
+
+/**
+ *    @file
+ *      This file implements unit tests for the Weave TLV implementation.
+ *
+ */
+
+#include "ToolCommon.h"
+
+#include <nlbyteorder.h>
+#include <nlunit-test.h>
+
+#include <Weave/Core/WeaveCore.h>
+#include <Weave/Core/WeaveTLV.h>
+#include <Weave/Core/WeaveTLVDebug.hpp>
+#include <Weave/Core/WeaveTLVUtilities.hpp>
+#include <Weave/Core/WeaveTLVData.hpp>
+#include <Weave/Core/WeaveCircularTLVBuffer.h>
+#include <Weave/Support/RandUtils.h>
+
+#include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h>
+#include <Weave/Profiles/data-management/DataManagement.h>
+
+#include <Weave/Profiles/data-management/WdmDictionary.h>
+
+#include <nest/test/trait/TestHTrait.h>
+#include <nest/test/trait/TestCTrait.h>
+#include <nest/test/trait/TestMismatchedCTrait.h>
+
+#include "MockMismatchedSchemaSinkAndSource.h"
+
+#include "MockTestBTrait.h"
+
+#include "MockPlatformClocks.h"
+
+#include <new>
+#include <map>
+#include <set>
+#include <algorithm>
+#include <set>
+#include <string>
+#include <iterator>
+
+#if WEAVE_SYSTEM_CONFIG_USE_LWIP
+#include <lwip/init.h>
+#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
+
+using namespace nl;
+using namespace nl::Weave::TLV;
+using namespace nl::Weave::Profiles::DataManagement;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// System/Platform definitions
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+namespace Private {
+
+System::Error SetClock_RealTime(uint64_t newCurTime)
+{
+    return WEAVE_SYSTEM_NO_ERROR;
+}
+
+static System::Error GetClock_RealTime(uint64_t & curTime)
+{
+    curTime = 0x42; // arbitrary non-zero value.
+    return WEAVE_SYSTEM_NO_ERROR;
+}
+
+} // namespace Private
+
+
+namespace nl {
+namespace Weave {
+namespace Profiles {
+namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) {
+namespace Platform {
+    // for unit tests, the dummy critical section is sufficient.
+    void CriticalSectionEnter()
+    {
+        return;
+    }
+
+    void CriticalSectionExit()
+    {
+        return;
+    }
+} // Platform
+} // WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current)
+}
+}
+}
+
+static SubscriptionEngine *gSubscriptionEngine;
+
+SubscriptionEngine * SubscriptionEngine::GetInstance()
+{
+    return gSubscriptionEngine;
+}
+
+static void TestTdmStatic_SingleLeafHandle(nlTestSuite *inSuite, void *inContext);
+
+// Test Suite
+
+/**
+ *  Test Suite that lists all the test functions.
+ */
+static const nlTest sTests[] = {
+    // Tests the static schema portions of TDM
+    NL_TEST_DEF("Test Tdm (Static schema): Single leaf handle", TestTdmStatic_SingleLeafHandle),
+    NL_TEST_SENTINEL()
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Testing NotificationEngine + TraitData
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace nl {
+namespace Weave {
+namespace Profiles {
+namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) {
+
+using namespace Schema::Nest::Test::Trait;
+
+class TestTdmSource : public TraitDataSource {
+public:
+    TestTdmSource();
+    void Reset();
+
+private:
+    WEAVE_ERROR GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter);
+    WEAVE_ERROR GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey);
+
+public:
+    // 
+    // The logical key here is the field 'da', which is of type uint32.
+    //
+    WdmDictionary<uint32_t, TestHTrait::StructDictionary> _dict;
+};
+
+TestTdmSource::TestTdmSource()
+    : TraitDataSource(&TestHTrait::TraitSchema)
+{
+    // Using the Modify method to insert and modify.
+    _dict.ModifyItem(1, [](auto &item) {
+        item._logical_key = 10;
+        item._data.da = 10;
+        item._data.db = 1;
+        item._data.dc = 2;
+    });
+
+    _dict.ModifyItem(2, [](auto &item) {
+        item._logical_key = 20;
+        item._data.da = 20;
+        item._data.db = 3;
+        item._data.dc = 4;
+    });
+}
+
+void TestTdmSource::Reset()
+{
+}
+
+WEAVE_ERROR TestTdmSource::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
+{
+    static WdmDictionary<uint32_t, TestHTrait::StructDictionary>::DictKeyTableTypeIterator it;
+
+    if (aContext == 0) {
+        it = _dict.GetDictKeyTable().begin();
+    }
+    else {
+        it++;
+    }
+
+    aContext = (uintptr_t)&it;
+
+    if (it == _dict.GetDictKeyTable().end()) {
+        return WEAVE_END_OF_INPUT;
+    }
+    else {
+        aKey = it->_dict_key;
+    }
+
+    return WEAVE_NO_ERROR;
+}
+
+WEAVE_ERROR TestTdmSource::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter)
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+    PropertyPathHandle dictionaryItemHandle = kNullPropertyPathHandle;
+
+    if (GetSchemaEngine()->IsInDictionary(aLeafHandle, dictionaryItemHandle)) {
+        PropertyPathHandle dictionaryHandle = GetSchemaEngine()->GetParent(dictionaryItemHandle);
+        PropertyDictionaryKey key = GetPropertyDictionaryKey(dictionaryItemHandle);
+
+        if (dictionaryHandle == TestHTrait::kPropertyHandle_L) {
+            auto it = _dict.GetDictKeyTable().find(key);
+
+            if (it != _dict.GetDictKeyTable().end()) {
+                TestHTrait::StructDictionary item = it->_data;
+                uint32_t val;
+
+                switch (GetPropertySchemaHandle(aLeafHandle)) {
+                    case TestHTrait::kPropertyHandle_L_Value_Da:
+                        WeaveLogDetail(DataManagement, "[TestTdmSource::GetLeafData] >> l[%u].da = %u", key, item.da);
+                        val = item.da;
+                        break;
+
+                    case TestHTrait::kPropertyHandle_L_Value_Db:
+                        WeaveLogDetail(DataManagement, "[TestTdmSource::GetLeafData] >> l[%u].db = %u", key, item.da);
+                        val = item.db;
+                        break;
+
+                    case TestHTrait::kPropertyHandle_L_Value_Dc:
+                        WeaveLogDetail(DataManagement, "[TestTdmSource::GetLeafData] >> l[%u].dc = %u", key, item.da);
+                        val = item.dc;
+                        break;
+
+                    default:
+                        WeaveLogError(DataManagement, "Unknown handle passed in!");
+                        return WEAVE_ERROR_INVALID_ARGUMENT;
+                        break;
+                }
+
+                err = aWriter.Put(aTagToWrite, val);
+                SuccessOrExit(err);
+            }
+            else {
+                WeaveLogError(DataManagement, "Requested key %u for dictionary handle %u that doesn't exist!", key, dictionaryHandle);
+                return WEAVE_ERROR_INVALID_ARGUMENT;
+            }
+        }
+    }
+
+exit:
+    return err;
+}
+
+
+class TestTdmSink : public TraitDataSink {
+public:
+    TestTdmSink();
+    void Reset();
+    void DumpChangeSets();
+
+private:
+    WEAVE_ERROR OnEvent(uint16_t aType, void *aInParam);
+    WEAVE_ERROR SetLeafData(PropertyPathHandle aLeafHandle, nl::Weave::TLV::TLVReader &aReader);
+
+public:
+    //
+    // Main canonical store of truth
+    //
+    WdmDictionary<uint32_t, TestHTrait::StructDictionary> _dict;
+
+    //
+    // Staged changes that are accrued and applied at the end
+    // of a logical change
+    //
+    WdmDictionary<uint32_t, TestHTrait::StructDictionary> _stagedDict;
+
+    //
+    // Staged set of deleted path handles
+    //
+    std::set<PropertyPathHandle> _deletedDictItems;
+
+    //
+    // Staged item that gets appended to the staged dictionary on completion
+    // of the modification.
+    WdmDictionary<uint32_t, TestHTrait::StructDictionary>::Item _stagedDictItem;
+
+    bool _isReplaceOperation;
+};
+
+TestTdmSink::TestTdmSink()
+    : TraitDataSink(&TestHTrait::TraitSchema)
+{
+}
+
+void TestTdmSink::Reset()
+{
+    ClearVersion();
+    _stagedDict.GetDictKeyTable().clear();
+    _deletedDictItems.clear();
+}
+
+WEAVE_ERROR TestTdmSink::OnEvent(uint16_t aType, void *aInParam)
+{
+    InEventParam *inParam = static_cast<InEventParam *>(aInParam);
+
+    switch (aType) {
+        case kEventChangeBegin:
+            _stagedDict.GetDictKeyTable().clear();
+            _deletedDictItems.clear();
+            _isReplaceOperation = false;
+            break;
+
+        case kEventDictionaryItemDelete:
+            WeaveLogError(DataManagement, "[TestTdmSink::OnEvent] Deleting %u:%u", 
+                          GetPropertyDictionaryKey(inParam->mDictionaryItemDelete.mTargetHandle), GetPropertySchemaHandle(inParam->mDictionaryItemDelete.mTargetHandle));
+
+
+            if (GetPropertySchemaHandle(inParam->mDictionaryItemDelete.mTargetHandle) == TestHTrait::kPropertyHandle_L) {
+                _deletedDictItems.insert(GetPropertyDictionaryKey(inParam->mDictionaryItemDelete.mTargetHandle));
+            }
+
+            break;
+
+        case kEventDictionaryItemModifyBegin:
+        {
+            auto it = _dict.GetDictKeyTable().find(GetPropertyDictionaryKey(inParam->mDictionaryItemModifyBegin.mTargetHandle));
+
+            WeaveLogError(DataManagement, "[TestTdmSink::OnEvent] Adding/Modifying %u:%u", GetPropertyDictionaryKey(inParam->mDictionaryItemModifyBegin.mTargetHandle), GetPropertySchemaHandle(inParam->mDictionaryItemModifyBegin.mTargetHandle));
+
+            _stagedDictItem._dict_key = GetPropertyDictionaryKey(inParam->mDictionaryItemModifyBegin.mTargetHandle);
+            if (it != _dict.GetDictKeyTable().end()) {
+                _stagedDictItem = *it;
+            }
+
+            break;
+        }
+
+        case kEventDictionaryItemModifyEnd:
+            _stagedDict.GetDictKeyTable().insert(_stagedDictItem);
+            break;
+
+        case kEventDictionaryReplaceBegin:
+            WeaveLogError(DataManagement, "[TestTdmSink::OnEvent] Replacing %u:%u", GetPropertyDictionaryKey(inParam->mDictionaryReplaceBegin.mTargetHandle), GetPropertySchemaHandle(inParam->mDictionaryReplaceBegin.mTargetHandle));
+
+            _isReplaceOperation = true;
+            _stagedDict.GetDictKeyTable().clear();
+            break;
+
+
+        case kEventChangeEnd:
+            WeaveLogError(DataManagement, "[TestTdmSink::OnEvent] Change End");
+           
+            //
+            // Delete items
+            // 
+            for (auto it = _deletedDictItems.begin(); it != _deletedDictItems.end(); it++) {
+                _dict.GetDictKeyTable().erase(*it);
+            }
+
+            _dict.ItemsAdded(_stagedDict, [](auto &i) {
+                printf("A %u: %u\n", i->_logical_key, i->_data.db);
+            }, true);
+
+            //
+            // Only do the negative intersection if we're doing a full replace on the dictionary. Otherwise, we'll
+            // unintentionally remove elements.
+            //
+            if (_isReplaceOperation) {
+                _dict.ItemsRemoved(_stagedDict, [](auto &i) {
+                    printf("R %u: %u\n", i->_logical_key, i->_data.db);
+                }, true);
+            }
+
+            _dict.ItemsModified(_stagedDict, [](auto &oldd, auto &newd) {
+                printf("M %u: %u %u\n", oldd->_logical_key, oldd->_data.db, newd->_data.db);
+            }, true);
+
+            break;
+    }
+
+    return WEAVE_NO_ERROR;
+}
+
+WEAVE_ERROR TestTdmSink::SetLeafData(PropertyPathHandle aHandle, TLVReader &aReader)
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+    PropertySchemaHandle schemaHandle = GetPropertySchemaHandle(aHandle);
+
+    WeaveLogError(DataManagement, "[TestTdmSink::SetLeafData] << %u:%u", GetPropertyDictionaryKey(aHandle), GetPropertySchemaHandle(aHandle));
+    
+    switch (schemaHandle) {
+        case TestHTrait::kPropertyHandle_L_Value_Da:
+        {
+            err = aReader.Get(_stagedDictItem._data.da);
+            SuccessOrExit(err);
+
+            _stagedDictItem._logical_key = _stagedDictItem._data.da;
+            break;
+        }
+
+        case TestHTrait::kPropertyHandle_L_Value_Db:
+        {
+            err = aReader.Get(_stagedDictItem._data.db);
+            SuccessOrExit(err);
+            break;
+        }
+
+        case TestHTrait::kPropertyHandle_L_Value_Dc:
+        {
+            err = aReader.Get(_stagedDictItem._data.dc);
+            SuccessOrExit(err);
+            break;
+        }
+    }
+
+exit:
+    return err;
+}
+
+class TestTdm {
+public:
+    TestTdm();
+
+    int Setup();
+    int Teardown();
+    int Reset();
+    int BuildAndProcessNotify();
+
+    void TestTdmStatic_SingleLeafHandle(nlTestSuite *inSuite);
+
+private:
+    SubscriptionHandler *mSubHandler;
+    SubscriptionClient *mSubClient;
+    NotificationEngine *mNotificationEngine;
+
+    SubscriptionEngine mSubscriptionEngine;
+    WeaveExchangeManager mExchangeMgr;
+    SingleResourceSourceTraitCatalog::CatalogItem mSourceCatalogStore[5];
+    SingleResourceSourceTraitCatalog mSourceCatalog;
+    SingleResourceSinkTraitCatalog::CatalogItem mSinkCatalogStore[5];
+    SingleResourceSinkTraitCatalog mSinkCatalog;
+    TestTdmSource mTestTdmSource;
+    TestTdmSink mTestTdmSink;
+    Binding *mClientBinding;
+    uint32_t mTestCase;
+    WEAVE_ERROR AllocateBuffer(uint32_t desiredSize, uint32_t minSize);
+};
+
+TestTdm::TestTdm()
+    : mSourceCatalog(ResourceIdentifier(ResourceIdentifier::SELF_NODE_ID), mSourceCatalogStore, 5),
+      mSinkCatalog(ResourceIdentifier(ResourceIdentifier::SELF_NODE_ID), mSinkCatalogStore, 5),
+      mClientBinding(NULL)
+{
+    mTestCase = 0;
+}
+
+int TestTdm::Setup()
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+    TraitDataHandle testTdmSourceHandle;
+    TraitDataHandle testTdmSinkHandle;
+    SubscriptionHandler::TraitInstanceInfo *traitInstance = NULL;
+
+    gSubscriptionEngine = &mSubscriptionEngine;
+
+    // Initialize SubEngine and set it up
+    err = mSubscriptionEngine.Init(&ExchangeMgr, NULL, NULL);
+    SuccessOrExit(err);
+
+    err = mSubscriptionEngine.EnablePublisher(NULL, &mSourceCatalog);
+    SuccessOrExit(err);
+
+    // Get a sub handler and prime it to the right state
+    err = mSubscriptionEngine.NewSubscriptionHandler(&mSubHandler);
+    SuccessOrExit(err);
+
+    mSubHandler->mBinding = ExchangeMgr.NewBinding();
+    mSubHandler->mBinding->BeginConfiguration().Transport_UDP();
+
+    mClientBinding = ExchangeMgr.NewBinding();
+
+    err = mSubscriptionEngine.NewClient(&mSubClient, mClientBinding, NULL, NULL, &mSinkCatalog, 0);
+    SuccessOrExit(err);
+
+    mNotificationEngine = &mSubscriptionEngine.mNotificationEngine;
+
+    mSourceCatalog.Add(0, &mTestTdmSource, testTdmSourceHandle);
+    mSinkCatalog.Add(0, &mTestTdmSink, testTdmSinkHandle);
+
+    traitInstance = mSubscriptionEngine.mTraitInfoPool;
+    mSubHandler->mTraitInstanceList = traitInstance;
+    mSubHandler->mNumTraitInstances++;
+    ++(SubscriptionEngine::GetInstance()->mNumTraitInfosInPool);
+
+    traitInstance->Init();
+    traitInstance->mTraitDataHandle = testTdmSourceHandle;
+    traitInstance->mRequestedVersion = 1;
+
+exit:
+    if (err != WEAVE_NO_ERROR) {
+        WeaveLogError(DataManagement, "Error setting up test: %d", err);
+    }
+
+    return err;
+}
+
+void TestTdm::TestTdmStatic_SingleLeafHandle(nlTestSuite *inSuite)
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+    bool testPass = false;
+
+    Reset();
+
+    //
+    // Replace
+    //
+    mTestTdmSource.Lock(); 
+    mTestTdmSource.SetDirty(TestHTrait::kPropertyHandle_L);
+    mTestTdmSource.Unlock();
+
+    err = BuildAndProcessNotify();
+    SuccessOrExit(err);
+
+    printf("Equal: %d\n", mTestTdmSource._dict.IsEqual(mTestTdmSink._dict));
+
+    //
+    // Delete Item
+    //
+    mTestTdmSource.Lock(); 
+    mTestTdmSource._dict.GetDictKeyTable().erase(0); 
+    mTestTdmSource.DeleteKey(CreatePropertyPathHandle(TestHTrait::kPropertyHandle_L_Value, 0));
+    mTestTdmSource.Unlock();
+
+    err = BuildAndProcessNotify();
+    SuccessOrExit(err);
+
+    printf("Equal: %d\n", mTestTdmSource._dict.IsEqual(mTestTdmSink._dict));
+   
+    //
+    // Add Item
+    //
+    mTestTdmSource.Lock();
+    mTestTdmSource._dict.ModifyItem(10, [](auto &i) {
+        i._logical_key = 300;
+        i._data.da = 300;
+        i._data.db = 30;
+        i._data.dc = 30;
+    });
+
+    mTestTdmSource.Lock(); 
+    mTestTdmSource.SetDirty(CreatePropertyPathHandle(TestHTrait::kPropertyHandle_L_Value, 10));
+    mTestTdmSource.Unlock();
+
+    err = BuildAndProcessNotify();
+    SuccessOrExit(err);
+
+    printf("Equal: %d\n", mTestTdmSource._dict.IsEqual(mTestTdmSink._dict));
+
+    //
+    // Change dictionary keys, but keep logical keys + data stable.
+    //
+    mTestTdmSource.Lock();
+    mTestTdmSource._dict.ModifyItem(10, [](auto &i) {
+        i._dict_key = 100;
+    });
+
+    mTestTdmSource._dict.ModifyItem(1, [](auto &i) {
+        i._dict_key = 1000;
+    });
+    
+    mTestTdmSource.SetDirty(TestHTrait::kPropertyHandle_L);
+    mTestTdmSource.Unlock();
+
+    err = BuildAndProcessNotify();
+    SuccessOrExit(err);
+
+    printf("Equal: %d\n", mTestTdmSource._dict.IsEqual(mTestTdmSink._dict));
+    
+    
+exit:
+    NL_TEST_ASSERT(inSuite, testPass);
+}
+
+int TestTdm::Teardown()
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+
+    if (mClientBinding != NULL)
+    {
+        mClientBinding->Release();
+        mClientBinding = NULL;
+    }
+
+    return err;
+}
+
+int TestTdm::Reset()
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+
+    mSubHandler->MoveToState(SubscriptionHandler::kState_SubscriptionEstablished_Idle);
+    
+    mTestTdmSink.Reset();
+    mTestTdmSource.Reset();
+
+    mNotificationEngine->mGraphSolver.ClearDirty();
+
+    return err;
+}
+
+int TestTdm::BuildAndProcessNotify()
+{
+    bool isSubscriptionClean;
+    NotificationEngine::NotifyRequestBuilder notifyRequest;
+    NotificationRequest::Parser notify;
+    PacketBuffer *buf = NULL;
+    TLVWriter writer;
+    TLVReader reader;
+    TLVType dummyType1, dummyType2;
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+    bool neWriteInProgress = false;
+    uint32_t maxNotificationSize = 0;
+    uint32_t maxPayloadSize = 0;
+
+    maxNotificationSize = mSubHandler->GetMaxNotificationSize();
+
+    err = mSubHandler->mBinding->AllocateRightSizedBuffer(buf, maxNotificationSize, WDM_MIN_NOTIFICATION_SIZE, maxPayloadSize);
+    SuccessOrExit(err);
+
+    err = notifyRequest.Init(buf, &writer, mSubHandler, maxPayloadSize);
+    SuccessOrExit(err);
+
+    err = mNotificationEngine->BuildSingleNotifyRequestDataList(mSubHandler, notifyRequest, isSubscriptionClean, neWriteInProgress);
+    SuccessOrExit(err);
+
+    if (neWriteInProgress)
+    {
+        err = notifyRequest.MoveToState(NotificationEngine::kNotifyRequestBuilder_Idle);
+        SuccessOrExit(err);
+
+        reader.Init(buf);
+
+        err = reader.Next();
+        SuccessOrExit(err);
+
+        notify.Init(reader);
+
+        err = notify.CheckSchemaValidity();
+        SuccessOrExit(err);
+
+        // Enter the struct
+        err = reader.EnterContainer(dummyType1);
+        SuccessOrExit(err);
+
+        // SubscriptionId
+        err = reader.Next();
+        SuccessOrExit(err);
+
+        err = reader.Next();
+        SuccessOrExit(err);
+
+        VerifyOrExit(nl::Weave::TLV::kTLVType_Array == reader.GetType(), err = WEAVE_ERROR_WRONG_TLV_TYPE);
+
+        err = reader.EnterContainer(dummyType2);
+        SuccessOrExit(err);
+
+        err = mSubClient->ProcessDataList(reader);
+        SuccessOrExit(err);
+    }
+    else
+    {
+        WeaveLogDetail(DataManagement, "nothing has been written");
+    }
+
+exit:
+    if (buf) {
+        PacketBuffer::Free(buf);
+    }
+
+    return err;
+}
+
+WEAVE_ERROR TestTdm::AllocateBuffer(uint32_t desiredSize, uint32_t minSize)
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+    uint32_t maxPayloadSize = 0;
+    PacketBuffer *buf = NULL;
+
+
+    err = mSubHandler->mBinding->AllocateRightSizedBuffer(buf, desiredSize, minSize, maxPayloadSize);
+    SuccessOrExit(err);
+
+exit:
+
+    if (buf)
+    {
+        PacketBuffer::Free(buf);
+    }
+
+    return err;
+}
+
+} // WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current)
+}
+}
+}
+
+TestTdm *gTestTdm;
+
+/**
+ *  Set up the test suite.
+ */
+static int TestSetup(void *inContext)
+{
+    static TestTdm testTdm;
+    gTestTdm = &testTdm;
+
+    return testTdm.Setup();
+}
+
+/**
+ *  Tear down the test suite.
+ */
+static int TestTeardown(void *inContext)
+{
+    return gTestTdm->Teardown();
+}
+
+static void TestTdmStatic_SingleLeafHandle(nlTestSuite *inSuite, void *inContext)
+{
+    gTestTdm->TestTdmStatic_SingleLeafHandle(inSuite);
+}
+
+/**
+ *  Main
+ */
+int main(int argc, char *argv[])
+{
+#if WEAVE_SYSTEM_CONFIG_USE_LWIP
+    tcpip_init(NULL, NULL);
+#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
+
+    MockPlatform::gMockPlatformClocks.GetClock_RealTime = Private::GetClock_RealTime;
+    MockPlatform::gMockPlatformClocks.SetClock_RealTime = Private::SetClock_RealTime;
+
+    nlTestSuite theSuite = {
+        "weave-tdm",
+        &sTests[0],
+        TestSetup,
+        TestTeardown
+    };
+
+    // Generate machine-readable, comma-separated value (CSV) output.
+    nl_test_set_output_style(OUTPUT_CSV);
+
+    // Run test suit against one context
+    nlTestRunner(&theSuite, NULL);
+
+    return nlTestRunnerStats(&theSuite);
+}
diff --git a/src/test-apps/schema/nest/test/trait/TestHTrait.h b/src/test-apps/schema/nest/test/trait/TestHTrait.h
index c3badd4..d7a1d75 100644
--- a/src/test-apps/schema/nest/test/trait/TestHTrait.h
+++ b/src/test-apps/schema/nest/test/trait/TestHTrait.h
@@ -186,6 +186,10 @@
     uint32_t db;
     uint32_t dc;
 
+    bool operator ==(const StructDictionary& a) const {
+        return (memcmp(&a, this, sizeof(StructDictionary)) == 0);
+    }
+
     static const nl::SchemaFieldDescriptor FieldSchema;
 
 };
