/*
 *
 *    Copyright (c) 2018 Google LLC.
 *    Copyright (c) 2016-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
 *      Sample mock trait data sinks that implement the simple and complex mock traits.
 */

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#include <stdint.h>
#include <inttypes.h>

// Note that the choice of namespace alias must be made up front for each and every compile unit
// This is because many include paths could set the default alias to unintended target.
#include <Weave/Profiles/bulk-data-transfer/Development/BDXManagedNamespace.hpp>
#include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h>

#include <Weave/Support/CodeUtils.h>
#include <Weave/Profiles/security/ApplicationKeysTrait.h>
#include <Weave/Profiles/security/ApplicationKeysStructSchema.h>
#include "ToolCommon.h"
#include "MockSinkTraits.h"
#include <schema/weave/common/DayOfWeekEnum.h>

using namespace ::nl::Weave;
using namespace ::nl::Weave::TLV;
using namespace ::nl::Weave::Profiles::DataManagement;
using namespace ::nl::Weave::Profiles::Security::AppKeys;

using namespace Weave::Trait::Locale;
using namespace Weave::Trait::Security;
using namespace Schema::Weave::Trait::Auth;
using namespace Schema::Weave::Trait::Auth::ApplicationKeysTrait;
using namespace Schema::Nest::Test::Trait;
using namespace Schema::Weave::Common;

static size_t MOCK_strlcpy(char * dst, const char * src, size_t size);

static size_t MOCK_strlcpy(char * dst, const char * src, size_t size)
{
    // note that srtncpy doesn't NUL-terminate the destination if source is too long
    strncpy(dst, src, size - 1);
    // forcifully NUL-terminate the destination
    dst[size - 1] = '\0';
    // keep compatibility with common strlcpy definition
    return strlen(src);
}

MockTraitDataSink::MockTraitDataSink(const TraitSchemaEngine * aEngine)
    : TraitDataSink(aEngine)
{
}

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
MockTraitUpdatableDataSink::MockTraitUpdatableDataSink(const TraitSchemaEngine * aEngine)
        : TraitUpdatableDataSink(aEngine)
{
}
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE

WEAVE_ERROR
MockTraitDataSourceDelegate::GetData(PropertyPathHandle aHandle,
                                     uint64_t aTagToWrite,
                                     nl::Weave::TLV::TLVWriter &aWriter,
                                     bool &aIsNull,
                                     bool &aIsPresent)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    aIsNull = false;
    aIsPresent = true;
    err = GetLeafData(aHandle, aTagToWrite, aWriter);

    return err;
}

LocaleSettingsTraitDataSink::LocaleSettingsTraitDataSink()
    : MockTraitDataSink(&LocaleSettingsTrait::TraitSchema)
{
    memset(mLocale, 0, sizeof(mLocale));
}

WEAVE_ERROR
LocaleSettingsTraitDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aLeafHandle) {
        case LocaleSettingsTrait::kPropertyHandle_active_locale:
            char next_locale[kMaxNumOfCharsPerLocale];
            err = aReader.GetString(next_locale, MAX_LOCALE_SIZE);
            SuccessOrExit(err);
            if (strncmp(next_locale, mLocale, MAX_LOCALE_SIZE) != 0)
            {
                WeaveLogDetail(DataManagement, "<<  active_locale is changed from \"%s\" to \"%s\"", mLocale, next_locale);
                memcpy(mLocale, next_locale, MAX_LOCALE_SIZE);
            }

            WeaveLogDetail(DataManagement, "<<  active_locale = \"%s\"", mLocale);
            break;

        default:
            WeaveLogDetail(DataManagement, "<<  UNKNOWN!");
            err = WEAVE_ERROR_TLV_TAG_NOT_FOUND;
    }

exit:
    return err;
}

WEAVE_ERROR
LocaleSettingsTraitDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aLeafHandle) {
        case LocaleSettingsTrait::kPropertyHandle_active_locale:
            err = aWriter.PutString(aTagToWrite, mLocale);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  active_locale = \"%s\"", mLocale);
            break;

        default:
            WeaveLogDetail(DataManagement, ">>  UNKNOWN!");
            ExitNow(err = WEAVE_ERROR_TLV_TAG_NOT_FOUND);
    }

exit:
    WeaveLogFunctError(err);

    return err;
}

WEAVE_ERROR LocaleSettingsTraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
{
    return WEAVE_END_OF_INPUT;
}

LocaleCapabilitiesTraitDataSink::LocaleCapabilitiesTraitDataSink()
    : MockTraitDataSink(&LocaleCapabilitiesTrait::TraitSchema),
      mNumLocales(0)
{
    memset(mLocales, 0, sizeof(mLocales));
}

WEAVE_ERROR
LocaleCapabilitiesTraitDataSink::OnEvent(uint16_t aType, void *aInParam)
{
    WeaveLogDetail(DataManagement, "LocaleCapabilitiesTraitDataSink::OnEvent event: %u", aType);
    return WEAVE_NO_ERROR;
}

WEAVE_ERROR
LocaleCapabilitiesTraitDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    char next_locale[kMaxNumOfCharsPerLocale];

    if (LocaleCapabilitiesTrait::kPropertyHandle_available_locales == aLeafHandle)
    {
        nl::Weave::TLV::TLVType OuterContainerType;

        // clear all locales
        mNumLocales = 0;

        VerifyOrExit(aReader.GetType() == nl::Weave::TLV::kTLVType_Array, err = WEAVE_ERROR_WRONG_TLV_TYPE);

        err = aReader.EnterContainer(OuterContainerType);
        SuccessOrExit(err);

        while (WEAVE_NO_ERROR == (err = aReader.Next()))
        {
            VerifyOrExit(nl::Weave::TLV::kTLVType_UTF8String == aReader.GetType(), err = WEAVE_ERROR_WRONG_TLV_TYPE);
            VerifyOrExit(nl::Weave::TLV::AnonymousTag == aReader.GetTag(), err = WEAVE_ERROR_INVALID_TLV_TAG);

            err = aReader.GetString(next_locale, kMaxNumOfCharsPerLocale);
            SuccessOrExit(err);
            if (strncmp(next_locale, mLocales[mNumLocales], MAX_LOCALE_SIZE) != 0)
            {
                 WeaveLogDetail(DataManagement,  "<<  locale[%u]  is changed from [%s] to [%s]", mNumLocales, mLocales[mNumLocales], next_locale);
                 memcpy(mLocales[mNumLocales], next_locale, MAX_LOCALE_SIZE);
            }

            WeaveLogDetail(DataManagement, "<<  locale[%u] = [%s]", mNumLocales, mLocales[mNumLocales]);

            ++mNumLocales;

            if (kMaxNumOfLocals == mNumLocales)
            {
                WeaveLogDetail(DataManagement, "Cannot handle more than %d locales, skip", kMaxNumOfLocals);
                break;
            }
        }

        // Note that ExitContainer internally skip all unread elements till the end of current container
        err = aReader.ExitContainer(OuterContainerType);
        SuccessOrExit(err);
    }
    else
    {
        WeaveLogDetail(DataManagement, "<<  UNKNOWN!");
        ExitNow(err = WEAVE_ERROR_INVALID_TLV_TAG);
    }

exit:
    return err;
}

WEAVE_ERROR
LocaleCapabilitiesTraitDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (LocaleCapabilitiesTrait::kPropertyHandle_available_locales == aLeafHandle) {
        nl::Weave::TLV::TLVType OuterContainerType;

        err = aWriter.StartContainer(aTagToWrite, nl::Weave::TLV::kTLVType_Array, OuterContainerType);
        SuccessOrExit(err);

        for (uint8_t i = 0; i < mNumLocales; ++i) {
            err = aWriter.PutString(nl::Weave::TLV::AnonymousTag, mLocales[i]);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  locale[%u] = [%s]", i, mLocales[i]);
        }

        err = aWriter.EndContainer(OuterContainerType);
        SuccessOrExit(err);
    }
    else {
        WeaveLogDetail(DataManagement, ">>  UNKNOWN!");
        ExitNow(err = WEAVE_ERROR_INVALID_TLV_TAG);
    }

    exit:
    WeaveLogFunctError(err);

    return err;
}

WEAVE_ERROR LocaleCapabilitiesTraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
{
    return WEAVE_END_OF_INPUT;
}

BoltLockSettingTraitDataSink::BoltLockSettingTraitDataSink()
    : MockTraitDataSink(&BoltLockSettingTrait::TraitSchema)
{
    mAutoRelockOn = false;
    mAutoRelockDuration = 0;
}

WEAVE_ERROR
BoltLockSettingTraitDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aLeafHandle) {
        case BoltLockSettingTrait::kPropertyHandle_auto_relock_on:
            bool next_autoRelockOn;
            err = aReader.Get(next_autoRelockOn);
            SuccessOrExit(err);
            if (next_autoRelockOn != mAutoRelockOn)
            {
                WeaveLogDetail(DataManagement, "<<  auto_relock_on is changed from %s to %s", mAutoRelockOn ? "true" : "false", next_autoRelockOn ? "true" : "false");
                mAutoRelockOn = next_autoRelockOn;
            }

            WeaveLogDetail(DataManagement, "<<  auto_relock_on = %s", mAutoRelockOn ? "true" : "false");
            break;

        case BoltLockSettingTrait::kPropertyHandle_auto_relock_duration:
            uint32_t aAutoRelockDuration;
            err = aReader.Get(aAutoRelockDuration);
            SuccessOrExit(err);
            if (aAutoRelockDuration != mAutoRelockDuration)
            {
                WeaveLogDetail(DataManagement, "<<  auto_relock_duration is changed from %u to %u", mAutoRelockDuration, aAutoRelockDuration);
                mAutoRelockDuration = aAutoRelockDuration;
            }

            WeaveLogDetail(DataManagement, "<<  auto_relock_duration = %u", mAutoRelockDuration);
            break;

        default:
            WeaveLogDetail(DataManagement, "<<  UNKNOWN!");
            err = WEAVE_ERROR_TLV_TAG_NOT_FOUND;
    }

exit:
    return err;
}

WEAVE_ERROR
BoltLockSettingTraitDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aLeafHandle) {
        case BoltLockSettingTrait::kPropertyHandle_auto_relock_on:
            err = aWriter.PutBoolean(aTagToWrite, mAutoRelockOn);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  auto_relock_on = %s", mAutoRelockOn ? "true" : "false");
            break;

        case BoltLockSettingTrait::kPropertyHandle_auto_relock_duration:
            err = aWriter.Put(aTagToWrite, mAutoRelockDuration);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  auto_relock_duration = %u", mAutoRelockDuration);
            break;

        default:
            WeaveLogDetail(DataManagement, ">>  UNKNOWN!");
            ExitNow(err = WEAVE_ERROR_TLV_TAG_NOT_FOUND);
    }

    exit:
    WeaveLogFunctError(err);
    return err;
}

WEAVE_ERROR BoltLockSettingTraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
{
    return WEAVE_END_OF_INPUT;
}

TestATraitDataSink::TestATraitDataSink()
    : MockTraitDataSink(&TestATrait::TraitSchema)
{
    taa = TestATrait::ENUM_A_VALUE_1;
    tab = TestCommon::COMMON_ENUM_A_VALUE_1;
    tac = 0;
    tad.saA = 0;
    tad.saB = false;

    for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) {
        tae[i] = 0;
    }
    for (size_t i = 0; i < sizeof(nullified_path) / sizeof(nullified_path[0]); i++)
    {
        nullified_path[i] = false;
    }
}

TestATraitDataSink::TestATraitDataSink(bool aAcceptsSublessNotifies)
    : MockTraitDataSink(&TestATrait::TraitSchema)
{
    TestATraitDataSink();

#if WDM_ENABLE_SUBSCRIPTIONLESS_NOTIFICATION
   SetAcceptsSubscriptionlessNotifications(aAcceptsSublessNotifies);
#endif // WDM_ENABLE_SUBSCRIPTIONLESS_NOTIFICATION
}

WEAVE_ERROR
TestATraitDataSink::OnEvent(uint16_t aType, void *aInParam)
{
    InEventParam *inParam = static_cast<InEventParam *>(aInParam);
    PropertyPathHandle handle;
    PropertyDictionaryKey key;

    switch (aType) {
        case kEventDictionaryReplaceBegin:
        case kEventDictionaryReplaceEnd:
        case kEventDictionaryItemModifyBegin:
        case kEventDictionaryItemModifyEnd:
            WeaveLogDetail(DataManagement, "TestATraitDataSink::OnEvent event: %u (handle: %08x)", aType, *(PropertyPathHandle *)aInParam);
            break;

        default:
            WeaveLogDetail(DataManagement, "TestATraitDataSink::OnEvent event: %u", aType);
    }

    switch (aType) {
        case kEventDictionaryReplaceBegin:
            handle = inParam->mDictionaryItemModifyBegin.mTargetHandle;

            if (handle == TestATrait::kPropertyHandle_TaI) {
                WeaveLogDetail(DataManagement, "Clearing out dictionary tai...");
                tai_map.clear();
            }
            else if (handle == TestATrait::kPropertyHandle_TaJ) {
                WeaveLogDetail(DataManagement, "Clearing out dictionary taj...");
                taj_map.clear();
            }
            else {
                WeaveLogDetail(DataManagement, "Unknown dictionary!");
            }

            break;

        case kEventDictionaryItemDelete:
            handle = inParam->mDictionaryItemDelete.mTargetHandle;
            key = GetPropertyDictionaryKey(handle);

            if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) {
                WeaveLogDetail(DataManagement, "Deleting key %u from tai...", key);
                tai_map.erase(key);
            }
            else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) {
                WeaveLogDetail(DataManagement, "Deleting key %u from taj...", key);
                taj_map.erase(key);
            }

            break;

        case kEventDictionaryItemModifyBegin:
            handle = inParam->mDictionaryItemModifyBegin.mTargetHandle;
            key = GetPropertyDictionaryKey(handle);

            if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) {
                if (tai_map.find(key) == tai_map.end()) {
                    WeaveLogDetail(DataManagement, "Staging new key %u for tai...", key);
                    memset(&tai_stageditem, 0, sizeof(tai_stageditem));
                }
                else {
                    WeaveLogDetail(DataManagement, "Modifying key %u in tai...", key);
                    tai_stageditem = tai_map[key];
                }
            }
            else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) {
                if (taj_map.find(key) == taj_map.end()) {
                    WeaveLogDetail(DataManagement, "Staging new key %u for taj...", key);
                    memset(&taj_stageditem, 0, sizeof(taj_stageditem));
                }
                else {
                    WeaveLogDetail(DataManagement, "Modifying key %u in taj...", key);
                    taj_stageditem = taj_map[key];
                }
            }

            break;

        case kEventDictionaryItemModifyEnd:
            handle = inParam->mDictionaryItemModifyEnd.mTargetHandle;
            key = GetPropertyDictionaryKey(handle);

            if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) {
                if (tai_map.find(key) == tai_map.end()) {
                    WeaveLogDetail(DataManagement, "Adding key %u to tai...", key);
                }

                tai_map[key] = tai_stageditem;
            }
            else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) {
                if (taj_map.find(key) == taj_map.end()) {
                    WeaveLogDetail(DataManagement, "Adding key %u to taj...", key);
                }

                taj_map[key] = taj_stageditem;
            }

            break;
    }

    return WEAVE_NO_ERROR;
}

void TestATraitDataSink::SetNullifiedPath(PropertyPathHandle aHandle, bool isNull)
{
    if (aHandle <= TestATrait::kPropertyHandle_TaJ_Value_SaB)
    {
        if (nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] != isNull)
        {
            nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] = isNull;
        }
    }
}


WEAVE_ERROR
TestATraitDataSink::SetData(PropertyPathHandle aHandle, TLVReader &aReader, bool aIsNull)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (aIsNull && !mSchemaEngine->IsNullable(aHandle))
    {
        WeaveLogDetail(DataManagement, "<< Non-nullable handle %d received a NULL", aHandle);

#if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0
        ExitNow(err = WEAVE_ERROR_INVALID_TLV_ELEMENT);
#endif
    }

    SetNullifiedPath(aHandle, aIsNull);

    if ((!aIsNull) && (mSchemaEngine->IsLeaf(aHandle)))
    {
        err = SetLeafData(aHandle, aReader);
        // set the parent handles to non-null
        while (aHandle != kRootPropertyPathHandle)
        {
            SetNullifiedPath(aHandle, aIsNull);
            aHandle = mSchemaEngine->GetParent(aHandle);
        }
    }

#if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0
exit:
#endif
    return err;
}

WEAVE_ERROR
TestATraitDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (GetPropertySchemaHandle(aLeafHandle)) {
        case TestATrait::kPropertyHandle_TaA:
            err = aReader.Get(taa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_a = %u", taa);
            break;

        case TestATrait::kPropertyHandle_TaB:
            err = aReader.Get(tab);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_b = %u", tab);
            break;

        case TestATrait::kPropertyHandle_TaC:
            uint32_t next_tac;
            err = aReader.Get(next_tac);
            SuccessOrExit(err);
            if (next_tac != tac)
            {
                WeaveLogDetail(DataManagement, "<<  ta_c is changed from %u to %u", tac, next_tac);
                tac = next_tac;
            }

            WeaveLogDetail(DataManagement, "<<  ta_c = %u", tac);
            break;

        case TestATrait::kPropertyHandle_TaD_SaA:
            uint32_t next_tad_saa;
            err = aReader.Get(next_tad_saa);
            SuccessOrExit(err);
            if (next_tad_saa != tad.saA)
            {
                WeaveLogDetail(DataManagement, "<<  ta_d.sa_a is changed from %u to %u", tad.saA, next_tad_saa);
                tad.saA = next_tad_saa;
            }

            WeaveLogDetail(DataManagement, "<<  ta_d.sa_a = %u", tad.saA);
            break;

        case TestATrait::kPropertyHandle_TaD_SaB:
            bool next_tad_sab;
            err = aReader.Get(next_tad_sab);
            SuccessOrExit(err);
            if (next_tad_sab != tad.saB)
            {
                WeaveLogDetail(DataManagement, "<<  ta_d.sa_b is changed from %u to %u", tad.saB, next_tad_sab);
                tad.saB = next_tad_sab;
            }

            WeaveLogDetail(DataManagement, "<<  ta_d.sa_b = %u", tad.saB);
            break;

        case TestATrait::kPropertyHandle_TaE:
        {
            TLVType outerType;
            uint32_t i = 0;

            err = aReader.EnterContainer(outerType);
            SuccessOrExit(err);

            while (((err = aReader.Next()) == WEAVE_NO_ERROR) && (i < (sizeof(tae) / sizeof(tae[0])))) {
                uint32_t next_tae;
                err = aReader.Get(next_tae);
                SuccessOrExit(err);
                if (tae[i] != next_tae)
                {
                    WeaveLogDetail(DataManagement, "<<  ta_e[%u] is changed from %u to %u", i, tae[i], next_tae);
                    tae[i] = next_tae;
                }

                WeaveLogDetail(DataManagement, "<<  ta_e[%u] = %u", i, tae[i]);
                i++;
            }

            err = aReader.ExitContainer(outerType);
            break;
        }

        case TestATrait::kPropertyHandle_TaG:
        {
            if (aReader.GetType() == kTLVType_UTF8String)
            {
                err = aReader.GetString(tag_string, sizeof(tag_string));
                SuccessOrExit(err);

                tag_use_ref = false;

                WeaveLogDetail(DataManagement, "<<  ta_g string = %s", tag_string);
            }
            else
            {
                err = aReader.Get(tag_ref);
                SuccessOrExit(err);

                tag_use_ref = true;

                WeaveLogDetail(DataManagement, "<<  ta_g ref = %u", tag_ref);
            }
        }
            break;

        case TestATrait::kPropertyHandle_TaK:
            err = aReader.GetBytes(&tak[0], sizeof(tak));
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_k %d bytes", sizeof(tak));
            break;

        case TestATrait::kPropertyHandle_TaL:
            err = aReader.Get(tal);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_l = %x", tal);
            break;

        case TestATrait::kPropertyHandle_TaM:
            err = aReader.Get(tam_resourceid);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_m = %" PRIx64 , tam_resourceid);
            break;

        case TestATrait::kPropertyHandle_TaN:
            err = aReader.GetBytes(&tan[0], sizeof(tan));
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_n %d bytes", sizeof(tan));
            DumpMemory(&tan[0], sizeof(tan), "WEAVE:DMG: <<  ta_n ", 16);
            break;

        case TestATrait::kPropertyHandle_TaO:
            err = aReader.Get(tao);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_o = %d", tao);
            break;

        case TestATrait::kPropertyHandle_TaP:
            int64_t next_tap;
            err = aReader.Get(next_tap);
            SuccessOrExit(err);

            if (next_tap != tap)
            {
                WeaveLogDetail(DataManagement, "<<  ta_p is changed from %d to %d", tap, next_tap);
                tap = next_tap;
            }
            WeaveLogDetail(DataManagement, "<<  ta_p = %d", tap);
            break;

        case TestATrait::kPropertyHandle_TaQ:
            err = aReader.Get(taq);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_q %" PRId64 , taq);
            break;

        case TestATrait::kPropertyHandle_TaR:
            err = aReader.Get(tar);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_r %u", tar);
            break;

        case TestATrait::kPropertyHandle_TaS:
            err = aReader.Get(tas);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_s %u", tas);
            break;

        case TestATrait::kPropertyHandle_TaT:
            err = aReader.Get(tat);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_t %u", tat);
            break;

        case TestATrait::kPropertyHandle_TaU:
            err = aReader.Get(tau);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_u %d", tau);
            break;

        case TestATrait::kPropertyHandle_TaV:
            err = aReader.Get(tav);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_v %u", tav);
            break;

        case TestATrait::kPropertyHandle_TaW:
            err = aReader.GetString(&taw[0], sizeof(taw));
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_w %s", taw);
            break;

        case TestATrait::kPropertyHandle_TaX:
            err = aReader.Get(tax);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_x %lf", tax);
            break;

        case TestATrait::kPropertyHandle_TaI_Value:
            err = aReader.Get(tai_stageditem);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  tai[%u] = %u", GetPropertyDictionaryKey(aLeafHandle), tai_stageditem);
            break;

        case TestATrait::kPropertyHandle_TaJ_Value_SaA:
            err = aReader.Get(taj_stageditem.saA);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  taj[%u].sa_a = %u", GetPropertyDictionaryKey(aLeafHandle), taj_stageditem.saA);
            break;

        case TestATrait::kPropertyHandle_TaJ_Value_SaB:
            err = aReader.Get(taj_stageditem.saB);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  taj[%u].sa_b = %u", GetPropertyDictionaryKey(aLeafHandle), taj_stageditem.saB);
            break;

        default:
            WeaveLogDetail(DataManagement, "<<  UNKNOWN!");
    }

exit:
    return err;
}

template <typename T>
WEAVE_ERROR GetNextDictionaryItemKeyHelper(std::map<uint16_t, T> *aMap, typename std::map<uint16_t, T>::iterator &it, uintptr_t &aContext, PropertyDictionaryKey &aKey)
{
    if (aContext == 0) {
        it = aMap->begin();
    }
    else {
        it++;
    }

    aContext = (uintptr_t)&it;
    if (it == aMap->end()) {
        return WEAVE_END_OF_INPUT;
    }
    else {
        aKey = it->first;
    }

    return WEAVE_NO_ERROR;
}

WEAVE_ERROR TestATraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
{
    static std::map<uint16_t, uint32_t>::iterator tai_iter;
    static std::map<uint16_t, TestATrait::StructA>::iterator taj_iter;

    if (aDictionaryHandle == TestATrait::kPropertyHandle_TaI) {
        return GetNextDictionaryItemKeyHelper(&tai_map, tai_iter, aContext, aKey);
    }
    else if (aDictionaryHandle == TestATrait::kPropertyHandle_TaJ) {
        return GetNextDictionaryItemKeyHelper(&taj_map, taj_iter, aContext, aKey);
    }

    return WEAVE_ERROR_INVALID_ARGUMENT;
}

WEAVE_ERROR TestATraitDataSink::GetData(PropertyPathHandle aHandle,
                                          uint64_t aTagToWrite,
                                          TLVWriter &aWriter,
                                          bool &aIsNull,
                                          bool &aIsPresent)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (mSchemaEngine->IsNullable(aHandle))
    {
        aIsNull = nullified_path[GetPropertySchemaHandle(aHandle) - TraitSchemaEngine::kHandleTableOffset];
    }
    else
    {
        aIsNull = false;
    }

    aIsPresent = true;

    // TDM will handle writing null
    if ((!aIsNull) && (aIsPresent) && (mSchemaEngine->IsLeaf(aHandle)))
    {
        err = GetLeafData(aHandle, aTagToWrite, aWriter);
    }

    return err;
}



WEAVE_ERROR TestATraitDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (GetPropertySchemaHandle(aLeafHandle)) {
        case TestATrait::kPropertyHandle_TaA:
            err = aWriter.Put(aTagToWrite, taa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_a = %u", taa);
            break;

        case TestATrait::kPropertyHandle_TaB:
            err = aWriter.Put(aTagToWrite, tab);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_b = %u", tab);
            break;

        case TestATrait::kPropertyHandle_TaC:
            err = aWriter.Put(aTagToWrite, tac);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_c = %u", tac);
            break;

        case TestATrait::kPropertyHandle_TaD_SaA:
            err = aWriter.Put(aTagToWrite, tad.saA);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_d.sa_a = %u", tad.saA);
            break;

        case TestATrait::kPropertyHandle_TaD_SaB:
            err = aWriter.PutBoolean(aTagToWrite, tad.saB);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_d.sa_b = %s", tad.saB ? "true" : "false");
            break;

        case TestATrait::kPropertyHandle_TaE:
        {
            TLVType outerType;

            err = aWriter.StartContainer(aTagToWrite, kTLVType_Array, outerType);
            SuccessOrExit(err);

            for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) {
                err = aWriter.Put(AnonymousTag, tae[i]);
                SuccessOrExit(err);

                WeaveLogDetail(DataManagement, ">>  ta_e[%u] = %u", i, tae[i]);
            }

            err = aWriter.EndContainer(outerType);
            break;
        }

        case TestATrait::kPropertyHandle_TaG:
        {
            if (tag_use_ref)
            {
                err = aWriter.Put(aTagToWrite, tag_ref);
                SuccessOrExit(err);

                WeaveLogDetail(DataManagement, ">>  ta_g ref = %u", tag_ref);
            }
            else
            {
                err = aWriter.PutString(aTagToWrite, tag_string);
                SuccessOrExit(err);

                WeaveLogDetail(DataManagement, ">>  ta_g string = %s", tag_string);
            }
        }
            break;

        case TestATrait::kPropertyHandle_TaH:
            // maybe TODO
            break;

        case TestATrait::kPropertyHandle_TaK:
            err = aWriter.PutBytes(aTagToWrite, tak, sizeof(tak));
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_k %d bytes", sizeof(tak));
            break;

        case TestATrait::kPropertyHandle_TaL:
            err = aWriter.Put(aTagToWrite, tal);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_l = %x", tal);
            break;

        case TestATrait::kPropertyHandle_TaM:
            err = aWriter.Put(aTagToWrite, tam_resourceid);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_m = %" PRIx64 , tam_resourceid);
            break;

        case TestATrait::kPropertyHandle_TaN:
            err = aWriter.PutBytes(aTagToWrite, tan, sizeof(tan));
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_n %d bytes", sizeof(tan));
            DumpMemory(&tan[0], sizeof(tan), "WEAVE:DMG: >>  ta_n ", 16);
            break;

        case TestATrait::kPropertyHandle_TaO:
            err = aWriter.Put(aTagToWrite, tao);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_o %u", tao);
            break;

        case TestATrait::kPropertyHandle_TaP:
            err = aWriter.Put(aTagToWrite, tap);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_p %" PRId64 , tap);
            break;

        case TestATrait::kPropertyHandle_TaQ:
            err = aWriter.Put(aTagToWrite, taq);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_q %" PRId64 , taq);
            break;

        case TestATrait::kPropertyHandle_TaR:
            err = aWriter.Put(aTagToWrite, tar);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_r %u", tar);
            break;

        case TestATrait::kPropertyHandle_TaS:
            err = aWriter.Put(aTagToWrite, tas);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_s %u", tas);
            break;

        case TestATrait::kPropertyHandle_TaT:
            err = aWriter.Put(aTagToWrite, tat);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_t %u", tat);
            break;

        case TestATrait::kPropertyHandle_TaU:
            err = aWriter.Put(aTagToWrite, tau);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_u %d", tau);
            break;

        case TestATrait::kPropertyHandle_TaV:
            err = aWriter.PutBoolean(aTagToWrite, tav);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_v %u", tav);
            break;

        case TestATrait::kPropertyHandle_TaW:
            err = aWriter.PutString(aTagToWrite, taw);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_w %s", taw);
            break;

        case TestATrait::kPropertyHandle_TaX:
            err = aWriter.Put(aTagToWrite, tax);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_x %lf", tax);
            break;

        case TestATrait::kPropertyHandle_TaI_Value:
        {
            PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle);

            err = aWriter.Put(aTagToWrite, tai_map[key]);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_i[%u] = %u", key, tai_map[key]);
            break;
        }

        case TestATrait::kPropertyHandle_TaJ_Value_SaA:
        {
            PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle);

            err = aWriter.Put(aTagToWrite, taj_map[key].saA);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_j[%u].sa_a = %u", key, taj_map[key].saA);
            break;
        }


        case TestATrait::kPropertyHandle_TaJ_Value_SaB:
        {
            PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle);

            err = aWriter.PutBoolean(aTagToWrite, taj_map[key].saB);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_j[%u].sa_b = %u", key, taj_map[key].saB);
            break;
        }

        default:
            WeaveLogDetail(DataManagement, ">>  TestATrait UNKNOWN! %08x", aLeafHandle);
    }

exit:
    WeaveLogFunctError(err);
    return err;
}

WEAVE_ERROR TestBTraitDataSink::GetData(PropertyPathHandle aHandle,
                                          uint64_t aTagToWrite,
                                          TLVWriter &aWriter,
                                          bool &aIsNull,
                                          bool &aIsPresent)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (mSchemaEngine->IsNullable(aHandle))
    {
        aIsNull = nullified_path[GetPropertySchemaHandle(aHandle) - TraitSchemaEngine::kHandleTableOffset];
    }
    else
    {
        aIsNull = false;
    }

    aIsPresent = true;

    // TDM will handle writing null
    if ((!aIsNull) && (aIsPresent) && (mSchemaEngine->IsLeaf(aHandle)))
    {
        err = GetLeafData(aHandle, aTagToWrite, aWriter);
    }

    return err;
}

WEAVE_ERROR TestBTraitDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aLeafHandle) {
        //
        // TestATrait
        //

        case TestBTrait::kPropertyHandle_TaA:
            err = aWriter.Put(aTagToWrite, taa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_a = %u", taa);
            break;

        case TestBTrait::kPropertyHandle_TaB:
            err = aWriter.Put(aTagToWrite, tab);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_b = %u", tab);
            break;

        case TestBTrait::kPropertyHandle_TaC:
            err = aWriter.Put(aTagToWrite, tac);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_c = %u", tac);
            break;

        case TestBTrait::kPropertyHandle_TaD_SaA:
            err = aWriter.Put(aTagToWrite, tad_saa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_d.sa_a = %u", tad_saa);
            break;

        case TestBTrait::kPropertyHandle_TaD_SaB:
            err = aWriter.PutBoolean(aTagToWrite, tad_sab);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_d.sa_b = %s", tad_sab ? "true" : "false");
            break;

        case TestBTrait::kPropertyHandle_TaP:
            err = aWriter.Put(aTagToWrite, tap);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_p = %d", tap);
            break;

        case TestBTrait::kPropertyHandle_TaE:
        {
            TLVType outerType;

            err = aWriter.StartContainer(aTagToWrite, kTLVType_Array, outerType);
            SuccessOrExit(err);

            for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) {
                err = aWriter.Put(AnonymousTag, tae[i]);
                SuccessOrExit(err);

                WeaveLogDetail(DataManagement, ">>  ta_e[%u] = %u", i, tae[i]);
            }

            err = aWriter.EndContainer(outerType);
            break;
        }

            //
            // TestBTrait
            //

        case TestBTrait::kPropertyHandle_TbA:
            err = aWriter.Put(aTagToWrite, tba);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_a = %u", tba);
            break;

        case TestBTrait::kPropertyHandle_TbB_SbA:
            err = aWriter.PutString(aTagToWrite, tbb_sba);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_b.sb_a = \"%s\"", tbb_sba);
            break;

        case TestBTrait::kPropertyHandle_TbB_SbB:
            err = aWriter.Put(aTagToWrite, tbb_sbb);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_b.sb_b = %u", tbb_sbb);
            break;

        case TestBTrait::kPropertyHandle_TbC_SaA:
            err = aWriter.Put(aTagToWrite, tbc_saa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_c.sa_a = %u", tbc_saa);
            break;

        case TestBTrait::kPropertyHandle_TbC_SaB:
            err = aWriter.PutBoolean(aTagToWrite, tbc_sab);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_c.sa_b = %s", tbc_sab ? "true" : "false");
            break;

        case TestBTrait::kPropertyHandle_TbC_SeaC:
            err = aWriter.PutString(aTagToWrite, tbc_seac);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_c.sea_c = %s", tbc_seac);
            break;

        default:
            WeaveLogDetail(DataManagement, ">>  UNKNOWN!");
    }

    exit:
    WeaveLogFunctError(err);
    return err;
}

WEAVE_ERROR TestBTraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
{
    return WEAVE_END_OF_INPUT;
}

TestBTraitDataSink::TestBTraitDataSink()
        : MockTraitDataSink(&TestBTrait::TraitSchema)
{
    taa = TestATrait::ENUM_A_VALUE_1;
    tab = TestCommon::COMMON_ENUM_A_VALUE_1;
    tac = 0;
    tad_saa = 0;
    tad_sab = false;

    for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) {
        tae[i] = 0;
    }

    strcpy(tai, "");

    tba = 0;
    strcpy(tbb_sba, "");
    tbb_sbb = 0;

    tbc_saa = 0;
    tbc_sab = false;
    strcpy(tbc_seac, "");

    for (size_t i = 0; i < sizeof(nullified_path) / sizeof(nullified_path[0]); i++)
    {
        nullified_path[i] = false;
    }
}

void TestBTraitDataSink::SetNullifiedPath(PropertyPathHandle aHandle, bool isNull)
{
    if (aHandle <= TestBTrait::kPropertyHandle_TaJ_Value_SaB)
    {
        if (nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] != isNull)
        {
            nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] = isNull;
        }
    }
}


WEAVE_ERROR
TestBTraitDataSink::SetData(PropertyPathHandle aHandle, TLVReader &aReader, bool aIsNull)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (aIsNull && !mSchemaEngine->IsNullable(aHandle))
    {
        WeaveLogDetail(DataManagement, "<< Non-nullable handle %d received a NULL", aHandle);

#if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0
        ExitNow(err = WEAVE_ERROR_INVALID_TLV_ELEMENT);
#endif
    }

    SetNullifiedPath(aHandle, aIsNull);

    if ((!aIsNull) && (mSchemaEngine->IsLeaf(aHandle)))
    {
        err = SetLeafData(aHandle, aReader);
        // set the parent handles to non-null
        while (aHandle != kRootPropertyPathHandle)
        {
            SetNullifiedPath(aHandle, aIsNull);
            aHandle = mSchemaEngine->GetParent(aHandle);
        }
    }

    return err;
}

WEAVE_ERROR
TestBTraitDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aLeafHandle) {
        //
        // TestATrait
        //

        case TestBTrait::kPropertyHandle_TaA:
            int32_t next_taa;
            err = aReader.Get(next_taa);
            SuccessOrExit(err);
            if (next_taa != taa)
            {
                WeaveLogDetail(DataManagement, "<<  ta_a is changed from %u to %u", taa, next_taa);
                taa = next_taa;
            }

            WeaveLogDetail(DataManagement, "<<  ta_a = %u", taa);
            break;

        case TestBTrait::kPropertyHandle_TaB:
            int32_t next_tab;
            err = aReader.Get(next_tab);
            SuccessOrExit(err);
            if (next_tab != tab)
            {
                WeaveLogDetail(DataManagement, "<<  ta_b is changed from %u to %u", tab, next_tab);
                tab = next_tab;
            }

            WeaveLogDetail(DataManagement, "<<  ta_b = %u", tab);
            break;

        case TestBTrait::kPropertyHandle_TaC:
            uint32_t next_tac;
            err = aReader.Get(next_tac);
            SuccessOrExit(err);
            if (next_tac != tac)
            {
                WeaveLogDetail(DataManagement, "<<  ta_c is changed from %u to %u", tac, next_tac);
                tac = next_tac;
            }

            WeaveLogDetail(DataManagement, "<<  ta_c = %u", tac);
            break;

        case TestBTrait::kPropertyHandle_TaD_SaA:
            uint32_t next_tad_saa;
            err = aReader.Get(next_tad_saa);
            SuccessOrExit(err);
            if (next_tad_saa != tad_saa)
            {
                WeaveLogDetail(DataManagement, "<<  ta_d.sa_a is changed from %u to %u", tad_saa, next_tad_saa);
                tad_saa = next_tad_saa;
            }

            WeaveLogDetail(DataManagement, "<<  ta_d.sa_a = %u", tad_saa);
            break;

        case TestBTrait::kPropertyHandle_TaD_SaB:
            bool next_tad_sab;
            err = aReader.Get(next_tad_sab);
            SuccessOrExit(err);
            if (next_tad_sab != tad_sab)
            {
                WeaveLogDetail(DataManagement, "<<  ta_d.sa_b is changed from %u to %u", tad_sab, next_tad_sab);
                tad_sab = next_tad_sab;
            }

            WeaveLogDetail(DataManagement, "<<  ta_d.sa_b = %u", tad_sab);
            break;

        case TestBTrait::kPropertyHandle_TaE:
        {
            TLVType outerType;
            uint32_t i = 0;

            err = aReader.EnterContainer(outerType);
            SuccessOrExit(err);

            while (((err = aReader.Next()) == WEAVE_NO_ERROR) && (i < (sizeof(tae) / sizeof(tae[0])))) {
                uint32_t next_tae;
                err = aReader.Get(next_tae);
                SuccessOrExit(err);
                if (tae[i] != next_tae)
                {
                    WeaveLogDetail(DataManagement, "<<  ta_e[%u] is changed from %u to %u", i, tae[i], next_tae);
                    tae[i] = next_tae;
                }

                WeaveLogDetail(DataManagement, "<<  ta_e[%u] = %u", i, tae[i]);
                i++;
            }

            err = aReader.ExitContainer(outerType);
            break;
        }

        case TestBTrait::kPropertyHandle_TaP:
            err = aReader.Get(tap);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_p = %" PRId64, tap);
            break;

            //
            // TestBTrait
            //

        case TestBTrait::kPropertyHandle_TbA:
            uint32_t next_tba;
            err = aReader.Get(next_tba);
            SuccessOrExit(err);
            if (tba != next_tba)
            {
                WeaveLogDetail(DataManagement, "<<  tb_a is changed from %u to %u", tba, next_tba);
                tba = next_tba;
            }

            WeaveLogDetail(DataManagement, "<<  tb_a = %u", tba);
            break;

        case TestBTrait::kPropertyHandle_TbB_SbA:
            char next_tbb_sba[MAX_ARRAY_LEN];
            err = aReader.GetString(next_tbb_sba, MAX_ARRAY_SIZE);
            SuccessOrExit(err);
            if (strncmp(tbb_sba, next_tbb_sba, MAX_ARRAY_SIZE))
            {
                WeaveLogDetail(DataManagement, "<<  tb_b.sb_a is changed from %s to %s", tbb_sba, next_tbb_sba);
                memcpy(tbb_sba, next_tbb_sba, MAX_ARRAY_SIZE);
            }

            WeaveLogDetail(DataManagement, "<<  tb_b.sb_a = %s", tbb_sba);
            break;

        case TestBTrait::kPropertyHandle_TbB_SbB:
            uint32_t next_tbb_sbb;
            err = aReader.Get(next_tbb_sbb);
            SuccessOrExit(err);
            if (tbb_sbb != next_tbb_sbb)
            {
                WeaveLogDetail(DataManagement, "<<  tb_b.sb_b is changed from %u to %u", tbb_sbb, next_tbb_sbb);
                tbb_sbb = next_tbb_sbb;
            }

            WeaveLogDetail(DataManagement, "<<  tb_b.sb_b = %u", tbb_sbb);
            break;

        case TestBTrait::kPropertyHandle_TbC_SaA:
            uint32_t next_tbc_saa;
            err = aReader.Get(next_tbc_saa);
            SuccessOrExit(err);
            if (tbc_saa != next_tbc_saa)
            {
                WeaveLogDetail(DataManagement, "<<  tb_c.sa_a is changed from %u to %u", tbc_saa, next_tbc_saa);
                tbc_saa = next_tbc_saa;
            }

            WeaveLogDetail(DataManagement, "<<  tb_c.sa_a = %u", tbc_saa);
            break;

        case TestBTrait::kPropertyHandle_TbC_SaB:
            bool next_tbc_sab;
            err = aReader.Get(next_tbc_sab);
            SuccessOrExit(err);
            if (tbc_sab != next_tbc_sab)
            {
                WeaveLogDetail(DataManagement, "<<  tb_c.sa_b is changed from %u to %u", tbc_sab, next_tbc_sab);
                tbc_sab = next_tbc_sab;
            }

            WeaveLogDetail(DataManagement, "<<  tb_c.sa_b = %u", tbc_sab);
            break;

        case TestBTrait::kPropertyHandle_TbC_SeaC:
            char next_tbc_seac[MAX_ARRAY_LEN];
            err = aReader.GetString(next_tbc_seac, MAX_ARRAY_SIZE);
            SuccessOrExit(err);
            if (strncmp(tbc_seac, next_tbc_seac, MAX_ARRAY_SIZE))
            {
                WeaveLogDetail(DataManagement, "<<  tb_c.sea_c is changed from \"%s\" to \"%s\"", tbc_seac, next_tbc_seac);
                memcpy(tbc_seac, next_tbc_seac, MAX_ARRAY_SIZE);
            }

            WeaveLogDetail(DataManagement, "<<  tb_c.sea_c = \"%s\"", tbc_seac);
            break;

        default:
            WeaveLogDetail(DataManagement, "<<  TestBTrait UNKNOWN! %08x", aLeafHandle);
    }

    exit:
    return err;
}

TestApplicationKeysTraitDataSink::TestApplicationKeysTraitDataSink(void)
{
}

enum
{
#if WEAVE_CONFIG_MAX_APPLICATION_EPOCH_KEYS > WEAVE_CONFIG_MAX_APPLICATION_GROUPS
    kMaxGroupKeysOfATypeCount                        = WEAVE_CONFIG_MAX_APPLICATION_EPOCH_KEYS,
#else
    kMaxGroupKeysOfATypeCount                        = WEAVE_CONFIG_MAX_APPLICATION_GROUPS,
#endif
};

WEAVE_ERROR TestApplicationKeysTraitDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TLVType outerContainerType;
    uint32_t keyType;
    uint32_t keyIds[kMaxGroupKeysOfATypeCount];
    uint8_t keyCount;
    WeaveGroupKey groupKey;

    VerifyOrExit(GroupKeyStore != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);

    if (ApplicationKeysTrait::kPropertyHandle_EpochKeys == aLeafHandle)
    {
        keyType = WeaveKeyId::kType_AppEpochKey;
    }
    else if (ApplicationKeysTrait::kPropertyHandle_MasterKeys == aLeafHandle)
    {
        keyType = WeaveKeyId::kType_AppGroupMasterKey;
    }
    else
    {
        ExitNow(err = WEAVE_ERROR_INVALID_TLV_TAG);
    }

    err = aWriter.StartContainer(aTagToWrite, kTLVType_Array, outerContainerType);
    SuccessOrExit(err);

    err = GroupKeyStore->EnumerateGroupKeys(keyType, keyIds, sizeof(keyIds) / sizeof(keyIds[0]), keyCount);
    SuccessOrExit(err);

    for (int i = 0; i < keyCount; ++i)
    {
        err = GroupKeyStore->GetGroupKey(keyIds[i], groupKey);
        SuccessOrExit(err);

        TLVType containerType2;

        err = aWriter.StartContainer(AnonymousTag, kTLVType_Structure, containerType2);
        SuccessOrExit(err);

        if (keyType == WeaveKeyId::kType_AppEpochKey)
        {
            const uint32_t epochKeyNumber = WeaveKeyId::GetEpochKeyNumber(groupKey.KeyId);
            err = aWriter.Put(ContextTag(kTag_EpochKey_KeyId), epochKeyNumber);
            SuccessOrExit(err);

            err = aWriter.Put(ContextTag(kTag_EpochKey_StartTime), (static_cast<int64_t>(groupKey.StartTime) * 1000));
            SuccessOrExit(err);

            err = aWriter.PutBytes(ContextTag(kTag_EpochKey_Key), groupKey.Key, groupKey.KeyLen);
            SuccessOrExit(err);

            err = aWriter.EndContainer(containerType2);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">> GroupEpochKeyId = %08" PRIX32, groupKey.KeyId);
        }
        // If master group key.
        else
        {
            err = aWriter.Put(ContextTag(kTag_ApplicationGroup_GlobalId), groupKey.GlobalId);
            SuccessOrExit(err);

            const uint32_t appGroupLocalNumber = WeaveKeyId::GetAppGroupLocalNumber(groupKey.KeyId);
            err = aWriter.Put(ContextTag(kTag_ApplicationGroup_ShortId), appGroupLocalNumber);
            SuccessOrExit(err);

            err = aWriter.PutBytes(ContextTag(kTag_ApplicationGroup_Key), groupKey.Key, groupKey.KeyLen);
            SuccessOrExit(err);

            err = aWriter.EndContainer(containerType2);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">> GroupMasterKeyId = %08" PRIX32, groupKey.KeyId);
        }
    }

    err = aWriter.EndContainer(outerContainerType);
    SuccessOrExit(err);

exit:

    WeaveLogFunctError(err);

    return err;
}

WEAVE_ERROR TestApplicationKeysTraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
{
    return WEAVE_END_OF_INPUT;
}

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
LocaleSettingsTraitUpdatableDataSink::LocaleSettingsTraitUpdatableDataSink()
        : MockTraitUpdatableDataSink(&LocaleSettingsTrait::TraitSchema)
{
    memset(mLocale, 0, sizeof(mLocale));
}

WEAVE_ERROR
LocaleSettingsTraitUpdatableDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aLeafHandle) {
        case LocaleSettingsTrait::kPropertyHandle_active_locale:
            char next_locale[kMaxNumOfCharsPerLocale];
            err = aReader.GetString(next_locale, MAX_LOCALE_SIZE);
            SuccessOrExit(err);
            if (strncmp(next_locale, mLocale, MAX_LOCALE_SIZE) != 0)
            {
                WeaveLogDetail(DataManagement, "<<  active_locale is changed from \"%s\" to \"%s\"", mLocale, next_locale);
                memcpy(mLocale, next_locale, MAX_LOCALE_SIZE);
            }

            WeaveLogDetail(DataManagement, "<<  active_locale = \"%s\"", mLocale);
            break;

        default:
            WeaveLogDetail(DataManagement, "<<  UNKNOWN!");
            err = WEAVE_ERROR_TLV_TAG_NOT_FOUND;
    }

    exit:
    return err;
}

WEAVE_ERROR
LocaleSettingsTraitUpdatableDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aLeafHandle) {
        case LocaleSettingsTrait::kPropertyHandle_active_locale:
            err = aWriter.PutString(aTagToWrite, mLocale);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  active_locale = \"%s\"", mLocale);
            break;

        default:
            WeaveLogDetail(DataManagement, ">>  UNKNOWN!");
            ExitNow(err = WEAVE_ERROR_TLV_TAG_NOT_FOUND);
    }

    exit:
    WeaveLogFunctError(err);

    return err;
}

WEAVE_ERROR LocaleSettingsTraitUpdatableDataSink::Mutate(SubscriptionClient * apSubClient,
                                                         bool aIsConditional,
                                                         MockWdmNodeOptions::WdmUpdateMutation aMutation)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    static unsigned int whichLocale = 0;
    static const char * locales[] = { "en-US", "zh-TW", "ja-JP", "pl-PL", "zh-CN" };
    PropertyPathHandle pathHandle = kNullPropertyPathHandle;

    Lock(apSubClient);

    MOCK_strlcpy(mLocale, locales[whichLocale], sizeof(mLocale));
    whichLocale = (whichLocale + 1) % (sizeof(locales)/sizeof(locales[0]));

    // This trait instance only supports the OneLeaf and Root mutations.

    switch (aMutation)
    {
    case MockWdmNodeOptions::kMutation_Root:
        pathHandle = LocaleSettingsTrait::kPropertyHandle_Root;
        break;

    case MockWdmNodeOptions::kMutation_OneLeaf:
    default:
        aMutation = MockWdmNodeOptions::kMutation_OneLeaf;
        pathHandle = LocaleSettingsTrait::kPropertyHandle_active_locale;
        break;
    }

    WeaveLogDetail(DataManagement, "<set updated> in 0x%08x", pathHandle);

    err = SetUpdated(apSubClient, pathHandle, aIsConditional);
    SuccessOrExit(err);

exit:
    WeaveLogDetail(DataManagement, "LocaleSettingsTrait mutated %s with error %d", MockWdmNodeOptions::GetMutationStrings()[aMutation], err);

    Unlock(apSubClient);

    return err;
}

WEAVE_ERROR LocaleSettingsTraitUpdatableDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
{
    return WEAVE_END_OF_INPUT;
}

WEAVE_ERROR TestATraitUpdatableDataSink::Mutate(SubscriptionClient * apSubClient,
                                                bool aIsConditional,
                                                MockWdmNodeOptions::WdmUpdateMutation aMutation)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Lock(apSubClient);

    WeaveLogDetail(DataManagement,
            "TestATraitUpdatableDataSink: mTraitTestSet: %" PRIu32 ", mTestCounter: %" PRIu32 "",
            mTraitTestSet, mTestCounter);

    switch (aMutation)
    {
    case MockWdmNodeOptions::kMutation_OneLeaf:
        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaP, aIsConditional);
        SuccessOrExit(err);

        tap++;

        break;

    case MockWdmNodeOptions::kMutation_SameLevelLeaves:
        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaP, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaC, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaR, aIsConditional);
        SuccessOrExit(err);

        tap++;
        tac++;
        tar++;

        break;

    case MockWdmNodeOptions::kMutation_DiffLevelLeaves:
        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD_SaB, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaA, aIsConditional);
        SuccessOrExit(err);

        if (taa == TestATrait::ENUM_A_VALUE_1) {
            taa = TestATrait::ENUM_A_VALUE_2;
        }
        else {
            taa = TestATrait::ENUM_A_VALUE_1;
        }

        tad.saB = !tad.saB;

        break;

    case MockWdmNodeOptions::kMutation_WholeDictionary:
    {
        uint32_t seed = 0;

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaI, aIsConditional);
        SuccessOrExit(err);

        if (tai_map[0] == seed)
        {
            // Just make sure we change the data
            seed = 100;
        }

        tai_map.clear();
        for (uint16_t i = 0; i < 10; i++) {
            tai_map[i] = { (uint32_t)i + seed };
        }

        break;
    }

    case MockWdmNodeOptions::kMutation_WholeLargeDictionary:
    {
        uint32_t seed = 0;

        // Add a leaf as well before the dictionary to prevent a regression; if the whole process
        // fails while encoding partial dictionaries, a retry will succeed only if the update context
        // has been reset properly; the reason is that if the dictionary encoder has left
        // stale state in the update context, the encoding of the leaf fails immediately.
        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaP, aIsConditional);
        SuccessOrExit(err);

        tap++;

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaI, aIsConditional);
        SuccessOrExit(err);

        if (tai_map[0] == seed)
        {
            // Just make sure we change the data
            seed = 100;
        }

        tai_map.clear();
        for (uint16_t i = 0; i < 800; i++) {
            tai_map[i] = { (uint32_t)i + 1 };
        }

        break;
    }

    case MockWdmNodeOptions::kMutation_FewDictionaryItems:
        err = SetUpdated(apSubClient, CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, 4), aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, 5), aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, 6), aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, 7), aIsConditional);
        SuccessOrExit(err);

        tai_map[4] = { 4 };
        tai_map[5] = { 5 };
        tai_map[6] = { 6 };
        tai_map[7] = { 7 };

        break;

    case MockWdmNodeOptions::kMutation_ManyDictionaryItems:
        for (size_t i = 0; i < 60; i++)
        {
            err = SetUpdated(apSubClient, CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, i), aIsConditional);
            SuccessOrExit(err);

            tai_map[i] = { static_cast<uint32_t>(i) };
        }

        break;

    case MockWdmNodeOptions::kMutation_WholeDictionaryAndLeaf:
        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaI, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaP, aIsConditional);
        SuccessOrExit(err);

        tai_map.clear();
        for (uint16_t i = 0; i < 10; i++) {
            tai_map[i] = { static_cast<uint32_t>(i) + 1 };
        }

        tap++;

        break;

    case MockWdmNodeOptions::kMutation_OneStructure:

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD, aIsConditional);
        SuccessOrExit(err);

        tad.saA = mTestCounter;
        tad.saB = !tad.saB;

        break;

    case MockWdmNodeOptions::kMutation_OneLeafOneStructure:

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaP, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD, aIsConditional);
        SuccessOrExit(err);

        tap++;

        tad.saA = mTestCounter;
        tad.saB = !tad.saB;

        break;

    case MockWdmNodeOptions::kMutation_Root:
        {

        Schema::Nest::Test::Trait::TestATrait::StructA tmpTajItem;

        // Root and some more subpaths
        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD_SaA, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaA, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaI, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_Root, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD, aIsConditional);
        SuccessOrExit(err);

        tai_map.clear();
        // test_weave_wdm_next_service_update_10_cond_Root_multi_traits.py depends on
        // the number of items added the to the dictionaries here
        for (uint16_t i = 0; i < 85; i++) {
            tai_map[i] = { ((uint32_t)i + 1)*10 + 7 };
        }

        taj_map.clear();
        tmpTajItem.saB = tad.saB;
        tmpTajItem.saA = 0;
        if (tmpTajItem.saB)
        {
            tmpTajItem.saA++;
        }
        for (uint16_t i = 0; i < 10; i++) {
            tmpTajItem.saA++;
            taj_map[i] = tmpTajItem;
        }

        if (taa == TestATrait::ENUM_A_VALUE_1) {
            taa = TestATrait::ENUM_A_VALUE_2;
        }
        else {
            taa = TestATrait::ENUM_A_VALUE_1;
        }

        tad.saB = !tad.saB;

        break;
        }

    case MockWdmNodeOptions::kMutation_RootWithLargeDictionary:

        err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_Root, aIsConditional);
        SuccessOrExit(err);

        tai_map.clear();
        for (uint16_t i = 0; i < 800; i++) {
            tai_map[i] = { ((uint32_t)i + 1)*10 + 3 };
        }

        tad.saB = !tad.saB;

        break;

    default:
        WeaveDie();
        break;
    }

    mTestCounter++;

exit:

    WeaveLogDetail(DataManagement, "TestATrait mutated %s with error %d", MockWdmNodeOptions::GetMutationStrings()[aMutation], err);

    Unlock(apSubClient);

    return err;
}

TestATraitUpdatableDataSink::TestATraitUpdatableDataSink()
        : MockTraitUpdatableDataSink(&TestATrait::TraitSchema)
{
    taa = TestATrait::ENUM_A_VALUE_1;
    tab = TestCommon::COMMON_ENUM_A_VALUE_1;
    tac = 0;
    tad.saA = 0;
    tad.saB = false;

    for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) {
        tae[i] = 0;
    }
    for (size_t i = 0; i < sizeof(nullified_path) / sizeof(nullified_path[0]); i++)
    {
        nullified_path[i] = false;
    }
}

WEAVE_ERROR
TestATraitUpdatableDataSink::OnEvent(uint16_t aType, void *aInParam)
{
    InEventParam *inParam = static_cast<InEventParam *>(aInParam);
    PropertyPathHandle handle;
    PropertyDictionaryKey key;

    switch (aType) {
        case kEventDictionaryReplaceBegin:
        case kEventDictionaryReplaceEnd:
        case kEventDictionaryItemModifyBegin:
        case kEventDictionaryItemModifyEnd:
            WeaveLogDetail(DataManagement, "TestATraitUpdatableDataSink::OnEvent event: %u (handle: %08x)", aType, *(PropertyPathHandle *)aInParam);
            break;

        default:
            WeaveLogDetail(DataManagement, "TestATraitUpdatableDataSink::OnEvent event: %u", aType);
    }

    switch (aType) {
        case kEventDictionaryReplaceBegin:
            handle = inParam->mDictionaryItemModifyBegin.mTargetHandle;

            if (handle == TestATrait::kPropertyHandle_TaI) {
                WeaveLogDetail(DataManagement, "Clearing out dictionary tai...");
                tai_map.clear();
            }
            else if (handle == TestATrait::kPropertyHandle_TaJ) {
                WeaveLogDetail(DataManagement, "Clearing out dictionary taj...");
                taj_map.clear();
            }
            else {
                WeaveLogDetail(DataManagement, "Unknown dictionary!");
            }

            break;

        case kEventDictionaryItemDelete:
            handle = inParam->mDictionaryItemDelete.mTargetHandle;
            key = GetPropertyDictionaryKey(handle);

            if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) {
                WeaveLogDetail(DataManagement, "Deleting key %u from tai...", key);
                tai_map.erase(key);
            }
            else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) {
                WeaveLogDetail(DataManagement, "Deleting key %u from taj...", key);
                taj_map.erase(key);
            }

            break;

        case kEventDictionaryItemModifyBegin:
            handle = inParam->mDictionaryItemModifyBegin.mTargetHandle;
            key = GetPropertyDictionaryKey(handle);

            if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) {
                if (tai_map.find(key) == tai_map.end()) {
                    WeaveLogDetail(DataManagement, "Staging new key %u for tai...", key);
                    memset(&tai_stageditem, 0, sizeof(tai_stageditem));
                }
                else {
                    WeaveLogDetail(DataManagement, "Modifying key %u in tai...", key);
                    tai_stageditem = tai_map[key];
                }
            }
            else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) {
                if (taj_map.find(key) == taj_map.end()) {
                    WeaveLogDetail(DataManagement, "Staging new key %u for taj...", key);
                    memset(&taj_stageditem, 0, sizeof(taj_stageditem));
                }
                else {
                    WeaveLogDetail(DataManagement, "Modifying key %u in taj...", key);
                    taj_stageditem = taj_map[key];
                }
            }

            break;

        case kEventDictionaryItemModifyEnd:
            handle = inParam->mDictionaryItemModifyEnd.mTargetHandle;
            key = GetPropertyDictionaryKey(handle);

            if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) {
                if (tai_map.find(key) == tai_map.end()) {
                    WeaveLogDetail(DataManagement, "Adding key %u to tai...", key);
                }

                tai_map[key] = tai_stageditem;
            }
            else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) {
                if (taj_map.find(key) == taj_map.end()) {
                    WeaveLogDetail(DataManagement, "Adding key %u to taj...", key);
                }

                taj_map[key] = taj_stageditem;
            }

            break;
    }

    return WEAVE_NO_ERROR;
}

void TestATraitUpdatableDataSink::SetNullifiedPath(PropertyPathHandle aHandle, bool isNull)
{
    if (aHandle <= TestATrait::kPropertyHandle_TaJ_Value_SaB)
    {
        if (nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] != isNull)
        {
            nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] = isNull;
        }
    }
}


WEAVE_ERROR
TestATraitUpdatableDataSink::SetData(PropertyPathHandle aHandle, TLVReader &aReader, bool aIsNull)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (aIsNull && !mSchemaEngine->IsNullable(aHandle))
    {
        WeaveLogDetail(DataManagement, "<< Non-nullable handle %d received a NULL", aHandle);

#if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0
        ExitNow(err = WEAVE_ERROR_INVALID_TLV_ELEMENT);
#endif
    }

    SetNullifiedPath(aHandle, aIsNull);

    if ((!aIsNull) && (mSchemaEngine->IsLeaf(aHandle)))
    {
        err = SetLeafData(aHandle, aReader);
        // set the parent handles to non-null
        while (aHandle != kRootPropertyPathHandle)
        {
            SetNullifiedPath(aHandle, aIsNull);
            aHandle = mSchemaEngine->GetParent(aHandle);
        }
    }

#if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0
exit:
#endif
    return err;
}

WEAVE_ERROR
TestATraitUpdatableDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (GetPropertySchemaHandle(aLeafHandle)) {
        case TestATrait::kPropertyHandle_TaA:
            err = aReader.Get(taa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_a = %u", taa);
            break;

        case TestATrait::kPropertyHandle_TaB:
            err = aReader.Get(tab);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_b = %u", tab);
            break;

        case TestATrait::kPropertyHandle_TaC:
            uint32_t next_tac;
            err = aReader.Get(next_tac);
            SuccessOrExit(err);
            if (next_tac != tac)
            {
                WeaveLogDetail(DataManagement, "<<  ta_c is changed from %u to %u", tac, next_tac);
                tac = next_tac;
            }

            WeaveLogDetail(DataManagement, "<<  ta_c = %u", tac);
            break;

        case TestATrait::kPropertyHandle_TaD_SaA:
            uint32_t next_tad_saa;
            err = aReader.Get(next_tad_saa);
            SuccessOrExit(err);
            if (next_tad_saa != tad.saA)
            {
                WeaveLogDetail(DataManagement, "<<  ta_d.sa_a is changed from %u to %u", tad.saA, next_tad_saa);
                tad.saA = next_tad_saa;
            }

            WeaveLogDetail(DataManagement, "<<  ta_d.sa_a = %u", tad.saA);
            break;

        case TestATrait::kPropertyHandle_TaD_SaB:
            bool next_tad_sab;
            err = aReader.Get(next_tad_sab);
            SuccessOrExit(err);
            if (next_tad_sab != tad.saB)
            {
                WeaveLogDetail(DataManagement, "<<  ta_d.sa_b is changed from %u to %u", tad.saB, next_tad_sab);
                tad.saB = next_tad_sab;
            }

            WeaveLogDetail(DataManagement, "<<  ta_d.sa_b = %u", tad.saB);
            break;

        case TestATrait::kPropertyHandle_TaE:
        {
            TLVType outerType;
            uint32_t i = 0;

            err = aReader.EnterContainer(outerType);
            SuccessOrExit(err);

            while (((err = aReader.Next()) == WEAVE_NO_ERROR) && (i < (sizeof(tae) / sizeof(tae[0])))) {
                uint32_t next_tae;
                err = aReader.Get(next_tae);
                SuccessOrExit(err);
                if (tae[i] != next_tae)
                {
                    WeaveLogDetail(DataManagement, "<<  ta_e[%u] is changed from %u to %u", i, tae[i], next_tae);
                    tae[i] = next_tae;
                }

                WeaveLogDetail(DataManagement, "<<  ta_e[%u] = %u", i, tae[i]);
                i++;
            }

            err = aReader.ExitContainer(outerType);
            break;
        }

        case TestATrait::kPropertyHandle_TaG:
        {
            if (aReader.GetType() == kTLVType_UTF8String)
            {
                err = aReader.GetString(tag_string, sizeof(tag_string));
                SuccessOrExit(err);

                tag_use_ref = false;

                WeaveLogDetail(DataManagement, "<<  ta_g string = %s", tag_string);
            }
            else
            {
                err = aReader.Get(tag_ref);
                SuccessOrExit(err);

                tag_use_ref = true;

                WeaveLogDetail(DataManagement, "<<  ta_g ref = %u", tag_ref);
            }
        }
            break;

        case TestATrait::kPropertyHandle_TaK:
            err = aReader.GetBytes(&tak[0], sizeof(tak));
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_k %d bytes", sizeof(tak));
            break;

        case TestATrait::kPropertyHandle_TaL:
            err = aReader.Get(tal);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_l = %x", tal);
            break;

        case TestATrait::kPropertyHandle_TaM:
            err = aReader.Get(tam_resourceid);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_m = %" PRIx64 , tam_resourceid);
            break;

        case TestATrait::kPropertyHandle_TaN:
            err = aReader.GetBytes(&tan[0], sizeof(tan));
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_n %d bytes", sizeof(tan));
            DumpMemory(&tan[0], sizeof(tan), "WEAVE:DMG: <<  ta_n ", 16);
            break;

        case TestATrait::kPropertyHandle_TaO:
            err = aReader.Get(tao);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_o = %d", tao);
            break;

        case TestATrait::kPropertyHandle_TaP:
            int64_t next_tap;
            err = aReader.Get(next_tap);
            SuccessOrExit(err);

            if (next_tap != tap)
            {
                WeaveLogDetail(DataManagement, "<<  ta_p is changed from %d to %d", tap, next_tap);
                tap = next_tap;
            }
            WeaveLogDetail(DataManagement, "<<  ta_p = %d", tap);
            break;

        case TestATrait::kPropertyHandle_TaQ:
            err = aReader.Get(taq);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_q %" PRId64 , taq);
            break;

        case TestATrait::kPropertyHandle_TaR:
            err = aReader.Get(tar);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_r %u", tar);
            break;

        case TestATrait::kPropertyHandle_TaS:
            err = aReader.Get(tas);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_s %u", tas);
            break;

        case TestATrait::kPropertyHandle_TaT:
            err = aReader.Get(tat);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_t %u", tat);
            break;

        case TestATrait::kPropertyHandle_TaU:
            err = aReader.Get(tau);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_u %d", tau);
            break;

        case TestATrait::kPropertyHandle_TaV:
            err = aReader.Get(tav);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_v %u", tav);
            break;

        case TestATrait::kPropertyHandle_TaW:
            err = aReader.GetString(&taw[0], sizeof(taw));
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_w %s", taw);
            break;

        case TestATrait::kPropertyHandle_TaX:
            err = aReader.Get(tax);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_x %lf", tax);
            break;

        case TestATrait::kPropertyHandle_TaI_Value:
            err = aReader.Get(tai_stageditem);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  tai[%u] = %u", GetPropertyDictionaryKey(aLeafHandle), tai_stageditem);
            break;

        case TestATrait::kPropertyHandle_TaJ_Value_SaA:
            err = aReader.Get(taj_stageditem.saA);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  taj[%u].sa_a = %u", GetPropertyDictionaryKey(aLeafHandle), taj_stageditem.saA);
            break;

        case TestATrait::kPropertyHandle_TaJ_Value_SaB:
            err = aReader.Get(taj_stageditem.saB);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  taj[%u].sa_b = %u", GetPropertyDictionaryKey(aLeafHandle), taj_stageditem.saB);
            break;

        default:
            WeaveLogDetail(DataManagement, "<<  UNKNOWN!");
    }

    exit:
    return err;
}

WEAVE_ERROR TestATraitUpdatableDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
{
    static std::map<uint16_t, uint32_t>::iterator tai_iter;
    static std::map<uint16_t, TestATrait::StructA>::iterator taj_iter;

    if (aDictionaryHandle == TestATrait::kPropertyHandle_TaI) {
        return GetNextDictionaryItemKeyHelper(&tai_map, tai_iter, aContext, aKey);
    }
    else if (aDictionaryHandle == TestATrait::kPropertyHandle_TaJ) {
        return GetNextDictionaryItemKeyHelper(&taj_map, taj_iter, aContext, aKey);
    }

    return WEAVE_ERROR_INVALID_ARGUMENT;
}

WEAVE_ERROR TestATraitUpdatableDataSink::GetData(PropertyPathHandle aHandle,
                                        uint64_t aTagToWrite,
                                        TLVWriter &aWriter,
                                        bool &aIsNull,
                                        bool &aIsPresent)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (mSchemaEngine->IsNullable(aHandle))
    {
        aIsNull = nullified_path[GetPropertySchemaHandle(aHandle) - TraitSchemaEngine::kHandleTableOffset];
    }
    else
    {
        aIsNull = false;
    }

    aIsPresent = true;

    // TDM will handle writing null
    if ((!aIsNull) && (aIsPresent) && (mSchemaEngine->IsLeaf(aHandle)))
    {
        err = GetLeafData(aHandle, aTagToWrite, aWriter);
    }

    return err;
}



WEAVE_ERROR TestATraitUpdatableDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (GetPropertySchemaHandle(aLeafHandle)) {
        case TestATrait::kPropertyHandle_TaA:
            err = aWriter.Put(aTagToWrite, taa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_a = %u", taa);
            break;

        case TestATrait::kPropertyHandle_TaB:
            err = aWriter.Put(aTagToWrite, tab);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_b = %u", tab);
            break;

        case TestATrait::kPropertyHandle_TaC:
            err = aWriter.Put(aTagToWrite, tac);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_c = %u", tac);
            break;

        case TestATrait::kPropertyHandle_TaD_SaA:
            err = aWriter.Put(aTagToWrite, tad.saA);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_d.sa_a = %u", tad.saA);
            break;

        case TestATrait::kPropertyHandle_TaD_SaB:
            err = aWriter.PutBoolean(aTagToWrite, tad.saB);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_d.sa_b = %s", tad.saB ? "true" : "false");
            break;

        case TestATrait::kPropertyHandle_TaE:
        {
            TLVType outerType;

            err = aWriter.StartContainer(aTagToWrite, kTLVType_Array, outerType);
            SuccessOrExit(err);

            for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) {
                err = aWriter.Put(AnonymousTag, tae[i]);
                SuccessOrExit(err);

                WeaveLogDetail(DataManagement, ">>  ta_e[%u] = %u", i, tae[i]);
            }

            err = aWriter.EndContainer(outerType);
            break;
        }

        case TestATrait::kPropertyHandle_TaG:
        {
            if (tag_use_ref)
            {
                err = aWriter.Put(aTagToWrite, tag_ref);
                SuccessOrExit(err);

                WeaveLogDetail(DataManagement, ">>  ta_g ref = %u", tag_ref);
            }
            else
            {
                err = aWriter.PutString(aTagToWrite, tag_string);
                SuccessOrExit(err);

                WeaveLogDetail(DataManagement, ">>  ta_g string = %s", tag_string);
            }
        }
            break;

        case TestATrait::kPropertyHandle_TaH:
            // maybe TODO
            break;

        case TestATrait::kPropertyHandle_TaK:
            err = aWriter.PutBytes(aTagToWrite, tak, sizeof(tak));
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_k %d bytes", sizeof(tak));
            break;

        case TestATrait::kPropertyHandle_TaL:
            err = aWriter.Put(aTagToWrite, tal);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_l = %x", tal);
            break;

        case TestATrait::kPropertyHandle_TaM:
            err = aWriter.Put(aTagToWrite, tam_resourceid);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_m = %" PRIx64 , tam_resourceid);
            break;

        case TestATrait::kPropertyHandle_TaN:
            err = aWriter.PutBytes(aTagToWrite, tan, sizeof(tan));
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_n %d bytes", sizeof(tan));
            DumpMemory(&tan[0], sizeof(tan), "WEAVE:DMG: >>  ta_n ", 16);
            break;

        case TestATrait::kPropertyHandle_TaO:
            err = aWriter.Put(aTagToWrite, tao);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_o %u", tao);
            break;

        case TestATrait::kPropertyHandle_TaP:
            err = aWriter.Put(aTagToWrite, tap);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_p %" PRId64 , tap);
            break;

        case TestATrait::kPropertyHandle_TaQ:
            err = aWriter.Put(aTagToWrite, taq);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_q %" PRId64 , taq);
            break;

        case TestATrait::kPropertyHandle_TaR:
            err = aWriter.Put(aTagToWrite, tar);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_r %u", tar);
            break;

        case TestATrait::kPropertyHandle_TaS:
            err = aWriter.Put(aTagToWrite, tas);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_s %u", tas);
            break;

        case TestATrait::kPropertyHandle_TaT:
            err = aWriter.Put(aTagToWrite, tat);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_t %u", tat);
            break;

        case TestATrait::kPropertyHandle_TaU:
            err = aWriter.Put(aTagToWrite, tau);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_u %d", tau);
            break;

        case TestATrait::kPropertyHandle_TaV:
            err = aWriter.PutBoolean(aTagToWrite, tav);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_v %u", tav);
            break;

        case TestATrait::kPropertyHandle_TaW:
            err = aWriter.PutString(aTagToWrite, taw);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_w %s", taw);
            break;

        case TestATrait::kPropertyHandle_TaX:
            err = aWriter.Put(aTagToWrite, tax);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_x %lf", tax);
            break;

        case TestATrait::kPropertyHandle_TaI_Value:
        {
            PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle);

            err = aWriter.Put(aTagToWrite, tai_map[key]);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_i[%u] = %u", key, tai_map[key]);
            break;
        }

        case TestATrait::kPropertyHandle_TaJ_Value_SaA:
        {
            PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle);

            err = aWriter.Put(aTagToWrite, taj_map[key].saA);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_j[%u].sa_a = %u", key, taj_map[key].saA);
            break;
        }


        case TestATrait::kPropertyHandle_TaJ_Value_SaB:
        {
            PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle);

            err = aWriter.PutBoolean(aTagToWrite, taj_map[key].saB);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_j[%u].sa_b = %u", key, taj_map[key].saB);
            break;
        }

        default:
            WeaveLogDetail(DataManagement, ">>  TestATrait UNKNOWN! %08x", aLeafHandle);
    }

    exit:
    WeaveLogFunctError(err);
    return err;
}

TestBTraitUpdatableDataSink::TestBTraitUpdatableDataSink()
    : MockTraitUpdatableDataSink(&TestBTrait::TraitSchema)
{
    taa = TestATrait::ENUM_A_VALUE_1;
    tab = TestCommon::COMMON_ENUM_A_VALUE_1;
    tac = 0;
    tad_saa = 0;
    tad_sab = false;

    for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) {
        tae[i] = 0;
    }

    strcpy(tai, "");

    tba = 0;
    strcpy(tbb_sba, "");
    tbb_sbb = 0;

    tbc_saa = 0;
    tbc_sab = false;
    strcpy(tbc_seac, "");

    for (size_t i = 0; i < sizeof(nullified_path) / sizeof(nullified_path[0]); i++)
    {
        nullified_path[i] = false;
    }
}

WEAVE_ERROR TestBTraitUpdatableDataSink::Mutate(SubscriptionClient * apSubClient,
                                                bool aIsConditional,
                                                MockWdmNodeOptions::WdmUpdateMutation aMutation)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    static int testNum = 0;
    const int numTests = 3;

    Lock(apSubClient);

    switch (aMutation)
    {
    case MockWdmNodeOptions::kMutation_OneLeafOneStructure:

        err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TbB_SbB, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TaA, aIsConditional);
        SuccessOrExit(err);

        if (taa == TestATrait::ENUM_A_VALUE_1) {
            taa = TestATrait::ENUM_A_VALUE_2;
        }
        else {
            taa = TestATrait::ENUM_A_VALUE_1;
        }

        tbb_sbb++;

        break;

    case MockWdmNodeOptions::kMutation_DiffLevelLeaves:

        err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TaC, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TaP, aIsConditional);
        SuccessOrExit(err);

        err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TbC_SaB, aIsConditional);
        SuccessOrExit(err);

        tap++;
        tac++;
        tbc_sab = !tbc_sab;

        break;

    case MockWdmNodeOptions::kMutation_OneLeaf:
    default:
        aMutation = MockWdmNodeOptions::kMutation_OneLeaf;

        err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TaP, aIsConditional);
        SuccessOrExit(err);

        tap++;
        break;
    }

    testNum = (testNum +1) % numTests;

exit:
    WeaveLogDetail(DataManagement, "TestBTrait mutated %s with error %d", MockWdmNodeOptions::GetMutationStrings()[aMutation], err);

    Unlock(apSubClient);

    return err;
}

void TestBTraitUpdatableDataSink::SetNullifiedPath(PropertyPathHandle aHandle, bool isNull)
{
    if (aHandle <= TestBTrait::kPropertyHandle_TaJ_Value_SaB)
    {
        if (nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] != isNull)
        {
            nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] = isNull;
        }
    }
}


WEAVE_ERROR
TestBTraitUpdatableDataSink::SetData(PropertyPathHandle aHandle, TLVReader &aReader, bool aIsNull)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (aIsNull && !mSchemaEngine->IsNullable(aHandle))
    {
        WeaveLogDetail(DataManagement, "<< Non-nullable handle %d received a NULL", aHandle);

#if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0
        ExitNow(err = WEAVE_ERROR_INVALID_TLV_ELEMENT);
#endif
    }

    SetNullifiedPath(aHandle, aIsNull);

    if ((!aIsNull) && (mSchemaEngine->IsLeaf(aHandle)))
    {
        err = SetLeafData(aHandle, aReader);
        // set the parent handles to non-null
        while (aHandle != kRootPropertyPathHandle)
        {
            SetNullifiedPath(aHandle, aIsNull);
            aHandle = mSchemaEngine->GetParent(aHandle);
        }
    }

    return err;
}

WEAVE_ERROR
TestBTraitUpdatableDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aLeafHandle) {
        //
        // TestATrait
        //

        case TestBTrait::kPropertyHandle_TaA:
            int32_t next_taa;
            err = aReader.Get(next_taa);
            SuccessOrExit(err);
            if (next_taa != taa)
            {
                WeaveLogDetail(DataManagement, "<<  ta_a is changed from %u to %u", taa, next_taa);
                taa = next_taa;
            }

            WeaveLogDetail(DataManagement, "<<  ta_a = %u", taa);
            break;

        case TestBTrait::kPropertyHandle_TaB:
            int32_t next_tab;
            err = aReader.Get(next_tab);
            SuccessOrExit(err);
            if (next_tab != tab)
            {
                WeaveLogDetail(DataManagement, "<<  ta_b is changed from %u to %u", tab, next_tab);
                tab = next_tab;
            }

            WeaveLogDetail(DataManagement, "<<  ta_b = %u", tab);
            break;

        case TestBTrait::kPropertyHandle_TaC:
            uint32_t next_tac;
            err = aReader.Get(next_tac);
            SuccessOrExit(err);
            if (next_tac != tac)
            {
                WeaveLogDetail(DataManagement, "<<  ta_c is changed from %u to %u", tac, next_tac);
                tac = next_tac;
            }

            WeaveLogDetail(DataManagement, "<<  ta_c = %u", tac);
            break;

        case TestBTrait::kPropertyHandle_TaD_SaA:
            uint32_t next_tad_saa;
            err = aReader.Get(next_tad_saa);
            SuccessOrExit(err);
            if (next_tad_saa != tad_saa)
            {
                WeaveLogDetail(DataManagement, "<<  ta_d.sa_a is changed from %u to %u", tad_saa, next_tad_saa);
                tad_saa = next_tad_saa;
            }

            WeaveLogDetail(DataManagement, "<<  ta_d.sa_a = %u", tad_saa);
            break;

        case TestBTrait::kPropertyHandle_TaD_SaB:
            bool next_tad_sab;
            err = aReader.Get(next_tad_sab);
            SuccessOrExit(err);
            if (next_tad_sab != tad_sab)
            {
                WeaveLogDetail(DataManagement, "<<  ta_d.sa_b is changed from %u to %u", tad_sab, next_tad_sab);
                tad_sab = next_tad_sab;
            }

            WeaveLogDetail(DataManagement, "<<  ta_d.sa_b = %u", tad_sab);
            break;

        case TestBTrait::kPropertyHandle_TaE:
        {
            TLVType outerType;
            uint32_t i = 0;

            err = aReader.EnterContainer(outerType);
            SuccessOrExit(err);

            while (((err = aReader.Next()) == WEAVE_NO_ERROR) && (i < (sizeof(tae) / sizeof(tae[0])))) {
                uint32_t next_tae;
                err = aReader.Get(next_tae);
                SuccessOrExit(err);
                if (tae[i] != next_tae)
                {
                    WeaveLogDetail(DataManagement, "<<  ta_e[%u] is changed from %u to %u", i, tae[i], next_tae);
                    tae[i] = next_tae;
                }

                WeaveLogDetail(DataManagement, "<<  ta_e[%u] = %u", i, tae[i]);
                i++;
            }

            err = aReader.ExitContainer(outerType);
            break;
        }

        case TestBTrait::kPropertyHandle_TaP:
            err = aReader.Get(tap);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  ta_p = %" PRId64, tap);
            break;

        //
        // TestBTrait
        //

        case TestBTrait::kPropertyHandle_TbA:
            uint32_t next_tba;
            err = aReader.Get(next_tba);
            SuccessOrExit(err);
            if (tba != next_tba)
            {
                WeaveLogDetail(DataManagement, "<<  tb_a is changed from %u to %u", tba, next_tba);
                tba = next_tba;
            }

            WeaveLogDetail(DataManagement, "<<  tb_a = %u", tba);
            break;

        case TestBTrait::kPropertyHandle_TbB_SbA:
            char next_tbb_sba[MAX_ARRAY_LEN];
            err = aReader.GetString(next_tbb_sba, MAX_ARRAY_SIZE);
            SuccessOrExit(err);
            if (strncmp(tbb_sba, next_tbb_sba, MAX_ARRAY_SIZE))
            {
                WeaveLogDetail(DataManagement, "<<  tb_b.sb_a is changed from %s to %s", tbb_sba, next_tbb_sba);
                memcpy(tbb_sba, next_tbb_sba, MAX_ARRAY_SIZE);
            }

            WeaveLogDetail(DataManagement, "<<  tb_b.sb_a = %s", tbb_sba);
            break;

        case TestBTrait::kPropertyHandle_TbB_SbB:
            uint32_t next_tbb_sbb;
            err = aReader.Get(next_tbb_sbb);
            SuccessOrExit(err);
            if (tbb_sbb != next_tbb_sbb)
            {
                WeaveLogDetail(DataManagement, "<<  tb_b.sb_b is changed from %u to %u", tbb_sbb, next_tbb_sbb);
                tbb_sbb = next_tbb_sbb;
            }

            WeaveLogDetail(DataManagement, "<<  tb_b.sb_b = %u", tbb_sbb);
            break;

        case TestBTrait::kPropertyHandle_TbC_SaA:
            uint32_t next_tbc_saa;
            err = aReader.Get(next_tbc_saa);
            SuccessOrExit(err);
            if (tbc_saa != next_tbc_saa)
            {
                WeaveLogDetail(DataManagement, "<<  tb_c.sa_a is changed from %u to %u", tbc_saa, next_tbc_saa);
                tbc_saa = next_tbc_saa;
            }

            WeaveLogDetail(DataManagement, "<<  tb_c.sa_a = %u", tbc_saa);
            break;

        case TestBTrait::kPropertyHandle_TbC_SaB:
            bool next_tbc_sab;
            err = aReader.Get(next_tbc_sab);
            SuccessOrExit(err);
            if (tbc_sab != next_tbc_sab)
            {
                WeaveLogDetail(DataManagement, "<<  tb_c.sa_b is changed from %u to %u", tbc_sab, next_tbc_sab);
                tbc_sab = next_tbc_sab;
            }

            WeaveLogDetail(DataManagement, "<<  tb_c.sa_b = %u", tbc_sab);
            break;

        case TestBTrait::kPropertyHandle_TbC_SeaC:
            char next_tbc_seac[MAX_ARRAY_LEN];
            err = aReader.GetString(next_tbc_seac, MAX_ARRAY_SIZE);
            SuccessOrExit(err);
            if (strncmp(tbc_seac, next_tbc_seac, MAX_ARRAY_SIZE))
            {
                WeaveLogDetail(DataManagement, "<<  tb_c.sea_c is changed from \"%s\" to \"%s\"", tbc_seac, next_tbc_seac);
                memcpy(tbc_seac, next_tbc_seac, MAX_ARRAY_SIZE);
            }

            WeaveLogDetail(DataManagement, "<<  tb_c.sea_c = \"%s\"", tbc_seac);
            break;

        default:
            WeaveLogDetail(DataManagement, "<<  TestBTrait UNKNOWN! %08x", aLeafHandle);
    }

exit:
    return err;
}


WEAVE_ERROR TestBTraitUpdatableDataSink::GetData(PropertyPathHandle aHandle,
                                        uint64_t aTagToWrite,
                                        TLVWriter &aWriter,
                                        bool &aIsNull,
                                        bool &aIsPresent)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (mSchemaEngine->IsNullable(aHandle))
    {
        aIsNull = nullified_path[GetPropertySchemaHandle(aHandle) - TraitSchemaEngine::kHandleTableOffset];
    }
    else
    {
        aIsNull = false;
    }

    aIsPresent = true;

    // TDM will handle writing null
    if ((!aIsNull) && (aIsPresent) && (mSchemaEngine->IsLeaf(aHandle)))
    {
        err = GetLeafData(aHandle, aTagToWrite, aWriter);
    }

    return err;
}

WEAVE_ERROR TestBTraitUpdatableDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aLeafHandle) {
        //
        // TestATrait
        //

        case TestBTrait::kPropertyHandle_TaA:
            err = aWriter.Put(aTagToWrite, taa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_a = %u", taa);
            break;

        case TestBTrait::kPropertyHandle_TaB:
            err = aWriter.Put(aTagToWrite, tab);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_b = %u", tab);
            break;

        case TestBTrait::kPropertyHandle_TaC:
            err = aWriter.Put(aTagToWrite, tac);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_c = %u", tac);
            break;

        case TestBTrait::kPropertyHandle_TaD_SaA:
            err = aWriter.Put(aTagToWrite, tad_saa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_d.sa_a = %u", tad_saa);
            break;

        case TestBTrait::kPropertyHandle_TaD_SaB:
            err = aWriter.PutBoolean(aTagToWrite, tad_sab);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_d.sa_b = %s", tad_sab ? "true" : "false");
            break;

        case TestBTrait::kPropertyHandle_TaP:
            err = aWriter.Put(aTagToWrite, tap);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_p = %d", tap);
            break;

        case TestBTrait::kPropertyHandle_TaE:
        {
            TLVType outerType;

            err = aWriter.StartContainer(aTagToWrite, kTLVType_Array, outerType);
            SuccessOrExit(err);

            for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) {
                err = aWriter.Put(AnonymousTag, tae[i]);
                SuccessOrExit(err);

                WeaveLogDetail(DataManagement, ">>  ta_e[%u] = %u", i, tae[i]);
            }

            err = aWriter.EndContainer(outerType);
            break;
        }

            //
            // TestBTrait
            //

        case TestBTrait::kPropertyHandle_TbA:
            err = aWriter.Put(aTagToWrite, tba);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_a = %u", tba);
            break;

        case TestBTrait::kPropertyHandle_TbB_SbA:
            err = aWriter.PutString(aTagToWrite, tbb_sba);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_b.sb_a = \"%s\"", tbb_sba);
            break;

        case TestBTrait::kPropertyHandle_TbB_SbB:
            err = aWriter.Put(aTagToWrite, tbb_sbb);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_b.sb_b = %u", tbb_sbb);
            break;

        case TestBTrait::kPropertyHandle_TbC_SaA:
            err = aWriter.Put(aTagToWrite, tbc_saa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_c.sa_a = %u", tbc_saa);
            break;

        case TestBTrait::kPropertyHandle_TbC_SaB:
            err = aWriter.PutBoolean(aTagToWrite, tbc_sab);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_c.sa_b = %s", tbc_sab ? "true" : "false");
            break;

        case TestBTrait::kPropertyHandle_TbC_SeaC:
            err = aWriter.PutString(aTagToWrite, tbc_seac);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tb_c.sea_c = %s", tbc_seac);
            break;

        default:
            WeaveLogDetail(DataManagement, ">>  UNKNOWN!");
    }

    exit:
    WeaveLogFunctError(err);
    return err;
}

WEAVE_ERROR TestBTraitUpdatableDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
{
    return WEAVE_END_OF_INPUT;
}

#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE
