/*
 *
 *    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
 *      This file defines the mock trait data sources for use with the mock device framework.
 *
 */

#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 "MockSourceTraits.h"
#include "TestGroupKeyStore.h"
#include "ToolCommon.h"

#include <Weave/Profiles/data-management/DataManagement.h>
#include <Weave/Profiles/security/ApplicationKeysTrait.h>
#include <Weave/Profiles/security/ApplicationKeysStructSchema.h>
#include <schema/weave/common/DayOfWeekEnum.h>


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);
}

LocaleSettingsTraitDataSource::LocaleSettingsTraitDataSource():
#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
     TraitUpdatableDataSource(&LocaleSettingsTrait::TraitSchema)
#else
     TraitDataSource(&LocaleSettingsTrait::TraitSchema)
#endif
{
    SetVersion(300);
    memset(mLocale, 0, sizeof(mLocale));
    MOCK_strlcpy(mLocale, "en-US", sizeof(mLocale));
}

void LocaleSettingsTraitDataSource::Mutate()
{
    static unsigned int whichLocale = 0;
    static const char * locales[] = { "en-US", "zh-TW", "ja-JP", "pl-PL", "zh-CN" };

    Lock();

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

    SetDirty(LocaleSettingsTrait::kPropertyHandle_active_locale);

    Unlock();
}

#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
WEAVE_ERROR
LocaleSettingsTraitDataSource::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aLeafHandle) {
        case LocaleSettingsTrait::kPropertyHandle_active_locale:
            char next_locale[24];
            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;
}

#endif // WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT

WEAVE_ERROR
LocaleSettingsTraitDataSource::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;
}

LocaleCapabilitiesTraitDataSource::LocaleCapabilitiesTraitDataSource()
#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
    :TraitUpdatableDataSource(&LocaleCapabilitiesTrait::TraitSchema)
#else
    :TraitDataSource(&LocaleCapabilitiesTrait::TraitSchema)
#endif
{
    SetVersion(400);

    memcpy(mLocales[0], "pl-PL", MAX_LOCALE_SIZE);
    memcpy(mLocales[1], "ja-JP", MAX_LOCALE_SIZE);
    memcpy(mLocales[2], "fr-FR", MAX_LOCALE_SIZE);
}

void LocaleCapabilitiesTraitDataSource::Mutate()
{
    Lock();

    switch (GetVersion() % 3) {
        case 0:
            mNumLocales = 2;
            memcpy(mLocales[0], "en-US", MAX_LOCALE_SIZE);
            memcpy(mLocales[1], "zh-TW", MAX_LOCALE_SIZE);
            break;

        case 1:
            mNumLocales = 1;
            memcpy(mLocales[0], "zh-CN", MAX_LOCALE_SIZE);
            break;

        case 2:
            mNumLocales = 3;
            memcpy(mLocales[0], "ja-JP", MAX_LOCALE_SIZE);
            memcpy(mLocales[1], "pl-PL", MAX_LOCALE_SIZE);
            memcpy(mLocales[2], "zh-CN", MAX_LOCALE_SIZE);
            break;
    }

    SetDirty(LocaleCapabilitiesTrait::kPropertyHandle_available_locales);

    Unlock();
}

#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
WEAVE_ERROR
LocaleCapabilitiesTraitDataSource::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;
}

#endif // WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT

WEAVE_ERROR
LocaleCapabilitiesTraitDataSource::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;
}

BoltLockSettingTraitDataSource::BoltLockSettingTraitDataSource()
    : TraitDataSource(&BoltLockSettingTrait::TraitSchema)
{
    SetVersion(500);

    mAutoRelockOn = false;
    mAutoRelockDuration = 2;
}

void BoltLockSettingTraitDataSource::Mutate()
{
    Lock();

    if ((GetVersion() % 2) == 0) {
        SetDirty(BoltLockSettingTrait::kPropertyHandle_auto_relock_on);
        mAutoRelockOn = !mAutoRelockOn;
    }
    else {
        SetDirty(BoltLockSettingTrait::kPropertyHandle_auto_relock_duration);
        mAutoRelockDuration++;
    }

    Unlock();
}

WEAVE_ERROR
BoltLockSettingTraitDataSource::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;
}

TestATraitDataSource::TestATraitDataSource():
#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
     TraitUpdatableDataSource(&TestATrait::TraitSchema),
#else
     TraitDataSource(&TestATrait::TraitSchema),
#endif
     mActiveCommand(NULL)
{
    uint8_t *tmp;
    SetVersion(100);
    mTestCounter = 0;
    taa = TestATrait::ENUM_A_VALUE_1;
    tab = TestCommon::COMMON_ENUM_A_VALUE_1;
    tac = 3;
    tad.saA = 4;
    tad.saB = true;

    mTraitTestSet = 0;

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

    tap = 1491859262000;

    tag_use_ref = false;
    tag_ref = 10;
    tam_resourceid = 0x18b4300000beefULL;
    tan_type = 1;

    tmp = &tan[0];
    nl::Weave::Encoding::LittleEndian::Write16(tmp, tan_type);
    nl::Weave::Encoding::LittleEndian::Write64(tmp, tam_resourceid);

    taq = -3000;
    tar = 3000;
    tas = 3000;

    tat = 1000;
    tau = -1000;
    tav = true;
    tax = 800;

    for (size_t i = 0; i < 4; i++) {
        tai_map[i] = 100 + i;
    }

    for (size_t i = 0; i < 4; i++) {
        taj_map[i] = { 300 + (uint32_t)i, true };
    }

    tal = DAY_OF_WEEK_SUNDAY;
}

void TestATraitDataSource::Mutate()
{
    Lock();
    uint8_t kNumTestCases;

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

    if (mTraitTestSet == 0)
    {
        kNumTestCases = 8;

        if ((mTestCounter % kNumTestCases) == 6) {
            // enums
            SetDirty(TestATrait::kPropertyHandle_TaD_SaA);
            SetDirty(TestATrait::kPropertyHandle_TaD_SaB);
            SetDirty(TestATrait::kPropertyHandle_TaA);

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

            tad.saA++;
            tad.saB = !tad.saB;
        }
        else if ((mTestCounter % kNumTestCases) == 1) {
            // timestamp and duration
            SetDirty(TestATrait::kPropertyHandle_TaP);
            SetDirty(TestATrait::kPropertyHandle_TaC);
            SetDirty(TestATrait::kPropertyHandle_TaR);
            SetDirty(TestATrait::kPropertyHandle_TaS);

            tap++;
            tac++;
            tar++;
            tas++;
        }
        else if ((mTestCounter % kNumTestCases) == 2) {
            // resource id, implicit and otherwise
            uint8_t *tmp = &tan[0];
            SetDirty(TestATrait::kPropertyHandle_TaM);
            SetDirty(TestATrait::kPropertyHandle_TaN);

            tan_type = (tan_type + 1) % 8;
            nl::Weave::Encoding::LittleEndian::Write16(tmp, tan_type);
        }
        else if ((mTestCounter % kNumTestCases) == 3) {
            // string ref
            SetDirty(TestATrait::kPropertyHandle_TaG);

            tag_use_ref = !tag_use_ref;
        }
        else if ((mTestCounter % kNumTestCases) == 4)
        {
            // day of week
            SetDirty(TestATrait::kPropertyHandle_TaL);

            tal ^= DAY_OF_WEEK_FRIDAY;
        }
        else if ((mTestCounter % kNumTestCases) == 5)
        {
            // boxed types
            SetDirty(TestATrait::kPropertyHandle_TaT);
            SetDirty(TestATrait::kPropertyHandle_TaU);
            SetDirty(TestATrait::kPropertyHandle_TaV);
            SetDirty(TestATrait::kPropertyHandle_TaW);
            SetDirty(TestATrait::kPropertyHandle_TaX);

            tat++;
            tau--;
            tav = !tav;
            tax++;
            if (tax > 808)
            {
                tax = -808;
            }
        }
        else if ((mTestCounter % kNumTestCases) == 0)
        {
            // nullified fields
            SetNullifiedPath(TestATrait::kPropertyHandle_TaD, true);
            SetNullifiedPath(TestATrait::kPropertyHandle_TaP, true);
            SetNullifiedPath(TestATrait::kPropertyHandle_TaS, true);
            SetNullifiedPath(TestATrait::kPropertyHandle_TaT, true);
            SetNullifiedPath(TestATrait::kPropertyHandle_TaM, true);
            SetNullifiedPath(TestATrait::kPropertyHandle_TaN, true);
        }
        else if ((mTestCounter % kNumTestCases) == 7)
        {
            // nullified fields
            SetNullifiedPath(TestATrait::kPropertyHandle_TaD, false);
            SetNullifiedPath(TestATrait::kPropertyHandle_TaP, false);
            SetNullifiedPath(TestATrait::kPropertyHandle_TaS, false);
            SetNullifiedPath(TestATrait::kPropertyHandle_TaT, false);
            SetNullifiedPath(TestATrait::kPropertyHandle_TaM, false);
            SetNullifiedPath(TestATrait::kPropertyHandle_TaN, false);
        }
    }
    else if (mTraitTestSet == 1)
    {
        printf("Flipping %u\n", mTestCounter % 14);

        // For dictionary testing, we need to do a couple of different directed tests.
        //
        // 0. Generate a notify directed at the dictionary for modification of the dictionary as a whole (path = parent of dictionary). This results in a replace of the dictionary (2nd level replace)
        // 1. Generate a notify directed at the dictionary item for modification of a single existing item (path = dictionary item)
        // 2. Generate a notify directed deep within a dictionary item for modification of a single existing item (path = deep in dictionary item)
        // 3. Generate a notify directed at the dictionary item for modification of multiple items (path = dictionary, merge operation)
        // 4. Generate a notify indicating the addition of multiplle dictionary items (path = dictionary, merge)
        // 5. Generate a notify indicating the deletion of a dictionary item (path = dictionary, delete)
        // 6. Generate a notify indicating the deletion of multiple dictionary items (path = dictionary, delete)
        // 7. Generate a notify indicating the deletion of multiple dictionary items that overflows delete handle set (path = parent of dictionary, replace)
        // 8. Generate a notify indicating the deletion of an item + addition of another item (path = dictionary, add + delete)
        // 9. Generate a notify indicating deletion of an item followed by the re-addition of that item (path = dictionary, modify of item).
        // 10. Generate a notify indicating the modification of an item followed by a deletion of that item (path = dictionary, delete of item).
        // 11. Generate a notify indicating the deletion of a single item from two different dictionaries (path = root)
        // 12. Generate a notify indicating the deletion of addition of a single item into two different dictionaries (path = root)
        // 13. Wipe out both dictionaries (path = root)
        // The line numbers above correspond to the various 'if' statement branches below.
        //

        if ((mTestCounter % 14) == 0) {
            SetDirty(TestATrait::kPropertyHandle_TaJ);

            for (uint32_t i = 0; i < 4; i++) {
                taj_map[i] = { 300 + (uint32_t)i, false };
            }
        }
        else if ((mTestCounter % 14) == 1) {
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 1));
            taj_map[1].saA += 100;
        }
        else if ((mTestCounter % 14) == 2) {
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value_SaA, 1));
            taj_map[1].saA += 100;
        }
        else if ((mTestCounter % 14) == 3) {
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 2));
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 3));

            taj_map[2].saA += 100;
            taj_map[3].saA += 100;
        }
        else if ((mTestCounter % 14) == 4) {
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 4));
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 5));
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 6));
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 7));
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 8));
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 9));
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 10));

            taj_map[4] = { 304, false };
            taj_map[5] = { 305, false };
            taj_map[6] = { 306, false };
            taj_map[7] = { 307, false };
            taj_map[8] = { 308, false };
            taj_map[9] = { 309, false };
            taj_map[10] = { 310, false };
        }
        else if ((mTestCounter % 14) == 5) {
            taj_map.erase(10);
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 10));
        }
        else if ((mTestCounter % 14) == 6) {
            taj_map.erase(9);
            taj_map.erase(8);
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 9));
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 8));
        }
        else if ((mTestCounter % 14) == 7) {
            taj_map.erase(7);
            taj_map.erase(6);
            taj_map.erase(5);
            taj_map.erase(4);
            taj_map.erase(3);

            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 7));
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 6));
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 5));
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 4));
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 3));
        }
        else if ((mTestCounter % 14) == 8) {
            taj_map.erase(2);
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 2));

            taj_map[3] = { 303, false };
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 3));
        }
        else if ((mTestCounter % 14) == 9) {
            TestATrait::StructA tmp = taj_map[3];

            taj_map.erase(3);
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 3));

            taj_map[3] = { tmp.saA + 100, tmp.saB };
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 3));
        }
        else if ((mTestCounter % 14) == 10) {
            taj_map[2].saA += 100;
            taj_map[2].saB = !taj_map[3].saB;
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 2));

            taj_map.erase(2);
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 2));
        }
        else if ((mTestCounter % 14) == 11) {
            taj_map.erase(3);
            tai_map.erase(3);
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 3));
            DeleteKey(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, 3));
        }
        else if ((mTestCounter % 14) == 12) {
            taj_map[3] = { 303, false };
            tai_map[3] = 103;
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaJ_Value, 3));
            SetDirty(CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, 3));
        }
        else if ((mTestCounter % 14) == 13) {
            taj_map.clear();
            tai_map.clear();

            for (int i = 0; i < 4; i++) {
                tai_map[i] = 100 + i;
            }

            SetDirty(TestATrait::kPropertyHandle_Root);
        }
    }
    else
    {
        // This is the behavior for WDM update tests

        kNumTestCases = 11;
        if ((mTestCounter % kNumTestCases) == 0) {
            //sink 3 leaf properties changes, source 3 leaf properties changes
            SetDirty(TestATrait::kPropertyHandle_TaP);
            SetDirty(TestATrait::kPropertyHandle_TaC);
            SetDirty(TestATrait::kPropertyHandle_TaR);

            tap++;
            tac++;
            tar++;
        }
        else if ((mTestCounter % kNumTestCases) == 1) {
            //sink 3 leaf properties changes, source 4 leaf properties changes
            SetDirty(TestATrait::kPropertyHandle_TaP);
            SetDirty(TestATrait::kPropertyHandle_TaC);
            SetDirty(TestATrait::kPropertyHandle_TaR);
            SetDirty(TestATrait::kPropertyHandle_TaS);

            tap++;
            tac++;
            tar++;
            tas++;
        }
        else if ((mTestCounter % kNumTestCases) == 2) {
            //sink 3 leaf properties changes, source 2 leaf properties changes
            SetDirty(TestATrait::kPropertyHandle_TaP);
            SetDirty(TestATrait::kPropertyHandle_TaC);

            tap++;
            tac++;
        }
        else if ((mTestCounter % kNumTestCases) == 3) {
            // mock sink, one independent leaf and one leaf in one structure property changes
            // mock source, one independent leaf and one leaf in one structure property changes
            //SetDirty(TestATrait::kPropertyHandle_TaD_SaA);
            SetDirty(TestATrait::kPropertyHandle_TaD_SaB);

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

            // tad.saA++;
            tad.saB = !tad.saB;
        }
        else if ((mTestCounter % kNumTestCases) == 4) {
            // sink, one independent leaf, one leaf in one structure property changes, mark this structure dirty, merge
            // source, one independent leaf and two leaf in one structure property changes
            SetDirty(TestATrait::kPropertyHandle_TaD_SaA);
            SetDirty(TestATrait::kPropertyHandle_TaA);
            SetDirty(TestATrait::kPropertyHandle_TaD);

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

            tad.saB = !tad.saB;
        }
        else if ((mTestCounter % kNumTestCases) == 5) {
            SetDirty(TestATrait::kPropertyHandle_TaI);

            for (uint16_t i = 0; i < 10; i++) {
                tai_map[i] = { (uint32_t)i + 1 };
            }
        }
        else if ((mTestCounter % kNumTestCases) == 6) {
            SetDirty(TestATrait::kPropertyHandle_TaI);

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

            SetDirty(TestATrait::kPropertyHandle_TaD_SaA);
            SetDirty(TestATrait::kPropertyHandle_TaA);
            SetDirty(TestATrait::kPropertyHandle_TaD);

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

            tad.saB = !tad.saB;
        }
        else if ((mTestCounter % kNumTestCases) == 7) {
            // sink, all merge with root handle, cut dictionary
            SetDirty(TestATrait::kPropertyHandle_Root);
            SetDirty(TestATrait::kPropertyHandle_TaD_SaA);
            SetDirty(TestATrait::kPropertyHandle_TaA);
            SetDirty(TestATrait::kPropertyHandle_TaD);
            SetDirty(TestATrait::kPropertyHandle_TaI);

            for (uint16_t i = 0; i < 10; i++) {
                tai_map[i] = { (uint32_t)i + 1 };
            }
            if (taa == TestATrait::ENUM_A_VALUE_1) {
                taa = TestATrait::ENUM_A_VALUE_2;
            }
            else {
                taa = TestATrait::ENUM_A_VALUE_1;
            }

            tad.saB = !tad.saB;
        }
        else if ((mTestCounter % kNumTestCases) == 8) {
            WeaveLogDetail(DataManagement, "Update member ta_d, which is a StructA");

            SetDirty(TestATrait::kPropertyHandle_TaD);

            tad.saA = mTestCounter;
            tad.saB = !tad.saB;
        }
        else if ((mTestCounter % kNumTestCases) == 9) {
            WeaveLogDetail(DataManagement, "all merge with root handle, cut dictionary");

            SetDirty(TestATrait::kPropertyHandle_Root);
            SetDirty(TestATrait::kPropertyHandle_TaD_SaA);
            SetDirty(TestATrait::kPropertyHandle_TaA);
            SetDirty(TestATrait::kPropertyHandle_TaD);
            SetDirty(TestATrait::kPropertyHandle_TaI);

            tai_map.clear();
            for (uint16_t i = 0; i < 3; i++) {
                tai_map[i] = { ((uint32_t)i + 1)*10 + 7 };
            }
            if (taa == TestATrait::ENUM_A_VALUE_1) {
                taa = TestATrait::ENUM_A_VALUE_2;
            }
            else {
                taa = TestATrait::ENUM_A_VALUE_1;
            }

            tad.saB = !tad.saB;
        }
        else if ((mTestCounter % kNumTestCases) == 10) {
            WeaveLogDetail(DataManagement, "all merge with root handle, cut oversized dictionary");
            SetDirty(TestATrait::kPropertyHandle_Root);
            SetDirty(TestATrait::kPropertyHandle_TaD_SaA);
            SetDirty(TestATrait::kPropertyHandle_TaA);
            SetDirty(TestATrait::kPropertyHandle_TaD);
            SetDirty(TestATrait::kPropertyHandle_TaI);

            tai_map.clear();
            for (uint16_t i = 0; i < 800; i++) {
                tai_map[i] = { (uint32_t)i + 1 };
            }
            if (taa == TestATrait::ENUM_A_VALUE_1) {
                taa = TestATrait::ENUM_A_VALUE_2;
            }
            else {
                taa = TestATrait::ENUM_A_VALUE_1;
            }

            tad.saB = !tad.saB;
        }
    }

    mTestCounter++;
    Unlock();
}

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 TestATraitDataSource::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);
    }
    else {
        return WEAVE_ERROR_INVALID_ARGUMENT;
    }
}

void TestATraitDataSource::SetNullifiedPath(PropertyPathHandle aHandle, bool isNull)
{
    if (aHandle <= TestATrait::kPropertyHandle_TaJ_Value_SaB)
    {
        if (nullified_path[aHandle - 1] != isNull)
        {
            nullified_path[aHandle - 1] = isNull;
            SetDirty(aHandle);
        }
    }
}

#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
WEAVE_ERROR
TestATraitDataSource::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 %d", 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;
}

#endif // WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT

WEAVE_ERROR TestATraitDataSource::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) - 1];
    }
    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 TestATraitDataSource::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 %d", 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, ">>  UNKNOWN! %08x", aLeafHandle);
    }

exit:
    WeaveLogFunctError(err);
    return err;
}

void TestATraitDataSource::HandleCommandOperationTimeout(nl::Weave::System::Layer* aSystemLayer, void *aAppState,
        nl::Weave::System::Error aErr)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TestATraitDataSource * const datasource = reinterpret_cast<TestATraitDataSource *>(aAppState);

    WeaveLogDetail(DataManagement, "Test trait A %s", __func__);

    VerifyOrExit (NULL != datasource->mActiveCommand, err = WEAVE_ERROR_INCORRECT_STATE);

    // If Command was OneWay, exit and close Command.

    VerifyOrExit(!datasource->mActiveCommand->IsOneWay(), err = WEAVE_NO_ERROR);

    // send back response for command type 2
    {

        PacketBuffer *msgBuf = PacketBuffer::New();
        if (NULL == msgBuf)
        {
            // It's unlikely we'll have packet buffer to send out the status report, but let us try anyways
            err = datasource->mActiveCommand->SendError(nl::Weave::Profiles::kWeaveProfile_Common,
                    nl::Weave::Profiles::Common::kStatus_OutOfMemory, WEAVE_ERROR_NO_MEMORY);
            datasource->mActiveCommand = NULL;
            ExitNow ();
        }

        // Add response data here
        {
            nl::Weave::TLV::TLVWriter writer;
            nl::Weave::TLV::TLVType dummyType;

            writer.Init(msgBuf);

            err = writer.StartContainer(nl::Weave::TLV::AnonymousTag, nl::Weave::TLV::kTLVType_Structure, dummyType);
            SuccessOrExit(err);

            err = writer.Put(nl::Weave::TLV::ContextTag(1), (datasource->mCommandParam_1) + 1);
            SuccessOrExit(err);
            err = writer.PutBoolean(nl::Weave::TLV::ContextTag(2), !(datasource->mCommandParam_2));
            SuccessOrExit(err);

            err = writer.EndContainer(dummyType);
            SuccessOrExit(err);

            err = writer.Finalize();
            SuccessOrExit(err);
        }

        // send using WRM only if the peer has asked for it
        err = datasource->mActiveCommand->SendResponse(datasource->GetVersion(), msgBuf);
        SuccessOrExit(err);

        datasource->mActiveCommand = NULL;
    }

exit:
    WeaveLogFunctError(err);

    if (NULL != datasource->mActiveCommand)
    {
        datasource->mActiveCommand->Close();
        datasource->mActiveCommand = NULL;
    }
}

void TestATraitDataSource::OnCustomCommand(nl::Weave::Profiles::DataManagement::Command * aCommand,
            const nl::Weave::WeaveMessageInfo * aMsgInfo,
            nl::Weave::PacketBuffer * aPayload,
            const uint64_t & aCommandType,
            const bool aIsExpiryTimeValid,
            const int64_t & aExpiryTimeMicroSecond,
            const bool aIsMustBeVersionValid,
            const uint64_t & aMustBeVersion,
            nl::Weave::TLV::TLVReader & aArgumentReader)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint32_t reportProfileId = nl::Weave::Profiles::kWeaveProfile_Common;
    uint16_t reportStatusCode = nl::Weave::Profiles::Common::kStatus_BadRequest;

    WeaveLogDetail(DataManagement, "Test trait A %s", __func__);

    // verify there is no active command already running
    // this is needed only if the implementation cannot handle more than one concurrent command per trait
    if (NULL != mActiveCommand)
    {
        // we already have one active command. Reject this new one directly
        reportProfileId = nl::Weave::Profiles::kWeaveProfile_Common;
        reportStatusCode = nl::Weave::Profiles::Common::kStatus_OutOfMemory;
        err = WEAVE_ERROR_NO_MEMORY;
        ExitNow ();
    }

    // verify if this command comes with a valid EC with the right peer node ID, key ID, and authenticator
    // more detailed example will be available when we have the security added

    // Note that the version check is passed to application layer because the application layer might want to know
    // someone is making a request.
    if (aIsMustBeVersionValid)
    {
        WeaveLogDetail(DataManagement, "Actual version is 0x%" PRIx64 ", while must-be version is: 0x%" PRIx64, GetVersion(), aMustBeVersion);

        if (aMustBeVersion != GetVersion())
        {
            reportProfileId = nl::Weave::Profiles::kWeaveProfile_WDM;
            reportStatusCode = kStatus_VersionMismatch;
            ExitNow ();
        }
    }

    WeaveLogDetail(DataManagement, "Command Type ID 0x%" PRIx64, aCommandType);

    // verify the command type and arguments are valid
    // command type 1: one shot signaling without custom data in response
    if (1 == aCommandType)
    {
        // Parse and validate the arguments according to schema definitions for this command
        {
            nl::Weave::TLV::TLVType OuterContainerType;
            err = aArgumentReader.EnterContainer(OuterContainerType);
            SuccessOrExit(err);

            while (WEAVE_NO_ERROR == (err = aArgumentReader.Next()))
            {
                // usually there is only context-specific tags in argument section
                VerifyOrExit(nl::Weave::TLV::IsContextTag(aArgumentReader.GetTag()), err = WEAVE_ERROR_INVALID_TLV_TAG);
                switch (nl::Weave::TLV::TagNumFromTag(aArgumentReader.GetTag()))
                {
                case kCmdParam_1:
                    err = aArgumentReader.Get(mCommandParam_1);
                    SuccessOrExit(err);
                    WeaveLogDetail(DataManagement, "Parameter 1: 0x%" PRIx32, mCommandParam_1);
                    break;

                case kCmdParam_2:
                    err = aArgumentReader.Get(mCommandParam_2);
                    SuccessOrExit(err);
                    WeaveLogDetail(DataManagement, "Parameter 2: %d", mCommandParam_2);
                    break;

                default:
                    // unrecognized arguments are allowed or not is a trait-specific question
                    ExitNow(err = WEAVE_ERROR_INVALID_TLV_TAG);
                }
            }

            if (WEAVE_END_OF_TLV == err)
            {
                // if any of the parameters are mandatory, we can verify at here
                err = WEAVE_NO_ERROR;
            }
            SuccessOrExit(err);
        }

        // Free the packet buffer after we parsed and processed/cached all arguments.
        // Doing this before allocating buffer for response might help reduce the max number of packet buffer needed
        PacketBuffer::Free(aPayload);
        aPayload = NULL;

        // If Command was OneWay, close Command and exit.

        if (aCommand->IsOneWay())
        {
            aCommand->Close();
            aCommand = NULL;
            ExitNow(err = WEAVE_NO_ERROR);
        }

        // Generate a success response right here
        {

            PacketBuffer * msgBuf = PacketBuffer::New();
            if (NULL == msgBuf)
            {
                // It's unlikely we'll have packet buffer to send out the status report, but let us try anyways
                reportProfileId = nl::Weave::Profiles::kWeaveProfile_Common;
                reportStatusCode = nl::Weave::Profiles::Common::kStatus_OutOfMemory;
                err = WEAVE_ERROR_NO_MEMORY;
                ExitNow ();
            }

            aCommand->SendResponse(GetVersion(), msgBuf);
            aCommand = NULL;
            msgBuf = NULL;
        }
    }
    // command type 2: with delayed, verifiable custom data in response
    else if (2 == aCommandType)
    {
        // Parse and validate the arguments according to schema definitions for this command
        {
            nl::Weave::TLV::TLVType OuterContainerType;
            err = aArgumentReader.EnterContainer(OuterContainerType);
            SuccessOrExit(err);

            while (WEAVE_NO_ERROR == (err = aArgumentReader.Next()))
            {
                // usually there is only context-specific tags in argument section
                VerifyOrExit(nl::Weave::TLV::IsContextTag(aArgumentReader.GetTag()), err = WEAVE_ERROR_INVALID_TLV_TAG);
                switch (nl::Weave::TLV::TagNumFromTag(aArgumentReader.GetTag()))
                {
                case kCmdParam_1:
                    err = aArgumentReader.Get(mCommandParam_1);
                    SuccessOrExit(err);
                    WeaveLogDetail(DataManagement, "Parameter 1: 0x%" PRIx32, mCommandParam_1);
                    break;

                case kCmdParam_2:
                    err = aArgumentReader.Get(mCommandParam_2);
                    SuccessOrExit(err);
                    WeaveLogDetail(DataManagement, "Parameter 2: %d", mCommandParam_2);
                    break;

                default:
                    // unrecognized arguments are allowed or not is a trait-specific question
                    ExitNow(err = WEAVE_ERROR_INVALID_TLV_TAG);
                }
            }

            if (WEAVE_END_OF_TLV == err)
            {
                // if any of the parameters are mandatory, we can verify at here
                err = WEAVE_NO_ERROR;
            }
            SuccessOrExit(err);
        }

        // Free the packet buffer after we parsed and processed/cached all arguments.
        // Doing this before allocating buffer for response might help reduce the max number of packet buffer needed
        PacketBuffer::Free(aPayload);
        aPayload = NULL;

        if (aCommand->IsOneWay())
        {
            aCommand->Close();
            aCommand = NULL;
            ExitNow(err = WEAVE_NO_ERROR);
        }

        // send back response later
        // note this is just an example of some operation which would take 2 seconds to complete
        // if the requested operation can be finished without delay, a response can be sent from here
        err = aCommand->GetExchangeContext()->ExchangeMgr->MessageLayer->SystemLayer->StartTimer(2000, HandleCommandOperationTimeout, this);
        SuccessOrExit(err);

        err = aCommand->SendInProgress();
        SuccessOrExit(err);

        // transfer ownership
        mActiveCommand = aCommand;
        aCommand = NULL;
    }
    else
    {
        // unrecognized command type id
        // default error is bad request
        err = WEAVE_ERROR_NOT_IMPLEMENTED;
        ExitNow();
    }


exit:
    WeaveLogFunctError(err);

    if (NULL != aCommand)
    {
        aCommand->SendError(reportProfileId, reportStatusCode, err);
        aCommand = NULL;
    }

    if (aPayload)
    {
        PacketBuffer::Free(aPayload);
        aPayload = NULL;
    }
}

TestBTraitDataSource::TestBTraitDataSource()
    : TraitDataSource(&TestBTrait::TraitSchema)
{
    SetVersion(200);
    taa = TestATrait::ENUM_A_VALUE_1;
    tab = TestCommon::COMMON_ENUM_A_VALUE_1;
    tac = 3;
    tad_saa = 4;
    tad_sab = true;

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

    tap = 101;

    tba = 200;
    MOCK_strlcpy(tbb_sba, "testing", sizeof(tbb_sba));
    tbb_sbb = 201;

    tbc_saa = 202;
    tbc_sab = false;
    MOCK_strlcpy(tbc_seac, "hallo", sizeof(tbc_seac));
}

void TestBTraitDataSource::Mutate()
{
    Lock();

    if ((GetVersion() % 3) == 0) {
        SetDirty(TestBTrait::kPropertyHandle_TbB_SbB);
        SetDirty(TestBTrait::kPropertyHandle_TaA);

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

        tbb_sbb++;
    }
    else if ((GetVersion() % 3) == 1) {
        SetDirty(TestBTrait::kPropertyHandle_TaC);
        SetDirty(TestBTrait::kPropertyHandle_TaP);
        SetDirty(TestBTrait::kPropertyHandle_TbC_SaB);

        tap++;
        tac++;
        tbc_sab = !tbc_sab;
    }
    else if ((GetVersion() % 3) == 2)
    {
        SetDirty(TestBTrait::kPropertyHandle_TaP);

        tap++;
    }

    Unlock();
}

WEAVE_ERROR TestBTraitDataSource::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_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 TestBTrait::kPropertyHandle_TaP:
            err = aWriter.Put(aTagToWrite, tap);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_p = %" PRId64, tap);
            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! %08x", aLeafHandle);
    }

exit:
    WeaveLogFunctError(err);
    return err;
}

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

TestBLargeTraitDataSource::TestBLargeTraitDataSource()
        : TraitDataSource(&TestBTrait::TraitSchema)
{
    SetVersion(200);
    taa = TestATrait::ENUM_A_VALUE_1;
    tab = TestCommon::COMMON_ENUM_A_VALUE_1;
    tac = 3;
    tad_saa = 4;
    tad_sab = true;

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

    tap = 0;

    tba = 200;
    MOCK_strlcpy(tbb_sba, "testing", sizeof(tbb_sba));
    tbb_sbb = 201;

    tbc_saa = 202;
    tbc_sab = false;
    MOCK_strlcpy(tbc_seac, "hallo", sizeof(tbc_seac));
}

void TestBLargeTraitDataSource::Mutate()
{
    Lock();

    if ((GetVersion() % 3) == 0) {
        SetDirty(TestBTrait::kPropertyHandle_TbB_SbB);
        SetDirty(TestBTrait::kPropertyHandle_TaA);

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

        tbb_sbb++;
    }
    else if ((GetVersion() % 3) == 1) {
        SetDirty(TestBTrait::kPropertyHandle_TaC);
        SetDirty(TestBTrait::kPropertyHandle_TaP);
        SetDirty(TestBTrait::kPropertyHandle_TbC_SaB);

        tap++;
        tac++;
        tbc_sab = !tbc_sab;
    }
    else if ((GetVersion() % 3) == 2) {
        SetDirty(TestBTrait::kPropertyHandle_TaP);

        tap++;
    }

    Unlock();
}

WEAVE_ERROR TestBLargeTraitDataSource::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_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 TestBTrait::kPropertyHandle_TaP:
            err = aWriter.Put(aTagToWrite, tap);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  ta_p = %d", tap);
            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 TestBLargeTraitDataSource::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
{
    return WEAVE_END_OF_INPUT;
}

ApplicationKeysTraitDataSource::ApplicationKeysTraitDataSource(void)
    : TraitDataSource(&ApplicationKeysTrait::TraitSchema)
{
    SetVersion(kInitialTraitVersionNumber);

    ClearEpochKeys();
    ClearGroupMasterKeys();

    AddEpochKey(sEpochKey1_Number, sEpochKey1_StartTime, sEpochKey1_Key, sEpochKey1_KeyLen);
    AddGroupMasterKey(sAppGroupMasterKey4_Number, sAppGroupMasterKey4_GlobalId, sAppGroupMasterKey4_Key, sAppGroupMasterKey4_KeyLen);
}

WEAVE_ERROR ApplicationKeysTraitDataSource::Mutate(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    bool mutateEpochKeys = true;
    bool mutateGroupMasterKeys = true;

    Lock();


    switch (GetVersion() % 3) {
        case 0:
            mutateEpochKeys = true;
            mutateGroupMasterKeys = false;
            break;

        case 1:
            mutateEpochKeys = false;
            mutateGroupMasterKeys = true;
            break;

        case 2:
            mutateEpochKeys = true;
            mutateGroupMasterKeys = true;
            break;
    }

    if (mutateEpochKeys)
    {
        err = MutateEpochKeys();
        SuccessOrExit(err);
    }

    if (mutateGroupMasterKeys)
    {
        err = MutateGroupMasterKeys();
        SuccessOrExit(err);
    }

exit:
    Unlock();

    return err;
}

WEAVE_ERROR ApplicationKeysTraitDataSource::MutateEpochKeys(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    ClearEpochKeys();

    // Picked 6 pairs of epoch keys, which rotate in the following order:
    // {0, 1} --> {1, 2} --> {2, 3} --> {3, 4} --> {4, 5} --> {5, 0}
    switch (GetVersion() % 6) {
        case 0:
            err = AddEpochKey(sEpochKey0_Number, sEpochKey0_StartTime, sEpochKey0_Key, sEpochKey0_KeyLen);
            SuccessOrExit(err);

            err = AddEpochKey(sEpochKey1_Number, sEpochKey1_StartTime, sEpochKey1_Key, sEpochKey1_KeyLen);
            SuccessOrExit(err);
            break;

        case 1:
            err = AddEpochKey(sEpochKey1_Number, sEpochKey1_StartTime, sEpochKey1_Key, sEpochKey1_KeyLen);
            SuccessOrExit(err);

            err = AddEpochKey(sEpochKey2_Number, sEpochKey2_StartTime, sEpochKey2_Key, sEpochKey2_KeyLen);
            SuccessOrExit(err);
            break;

        case 2:
            err = AddEpochKey(sEpochKey2_Number, sEpochKey2_StartTime, sEpochKey2_Key, sEpochKey2_KeyLen);
            SuccessOrExit(err);

            err = AddEpochKey(sEpochKey3_Number, sEpochKey3_StartTime, sEpochKey3_Key, sEpochKey3_KeyLen);
            SuccessOrExit(err);
            break;

        case 3:
            err = AddEpochKey(sEpochKey3_Number, sEpochKey3_StartTime, sEpochKey3_Key, sEpochKey3_KeyLen);
            SuccessOrExit(err);

            err = AddEpochKey(sEpochKey4_Number, sEpochKey4_StartTime, sEpochKey4_Key, sEpochKey4_KeyLen);
            SuccessOrExit(err);
            break;

        case 4:
            err = AddEpochKey(sEpochKey4_Number, sEpochKey4_StartTime, sEpochKey4_Key, sEpochKey4_KeyLen);
            SuccessOrExit(err);

            err = AddEpochKey(sEpochKey5_Number, sEpochKey5_StartTime, sEpochKey5_Key, sEpochKey5_KeyLen);
            SuccessOrExit(err);
            break;

        case 5:
            err = AddEpochKey(sEpochKey5_Number, sEpochKey5_StartTime, sEpochKey5_Key, sEpochKey5_KeyLen);
            SuccessOrExit(err);

            err = AddEpochKey(sEpochKey0_Number, sEpochKey0_StartTime, sEpochKey0_Key, sEpochKey0_KeyLen);
            SuccessOrExit(err);
            break;
    }

exit:
    SetDirty(ApplicationKeysTrait::kPropertyHandle_EpochKeys);

    return err;
}

WEAVE_ERROR ApplicationKeysTraitDataSource::MutateGroupMasterKeys(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    ClearGroupMasterKeys();

    // Picked 5 (arbitrary) sets of group master keys to test key update fanctionality.
    switch (GetVersion() % 5) {
        case 0:
            err = AddGroupMasterKey(sAppGroupMasterKey10_Number, sAppGroupMasterKey10_GlobalId, sAppGroupMasterKey10_Key, sAppGroupMasterKey10_KeyLen);
            SuccessOrExit(err);

            err = AddGroupMasterKey(sAppGroupMasterKey7_Number, sAppGroupMasterKey7_GlobalId, sAppGroupMasterKey7_Key, sAppGroupMasterKey7_KeyLen);
            SuccessOrExit(err);
            break;

        case 1:
            err = AddGroupMasterKey(sAppGroupMasterKey0_Number, sAppGroupMasterKey0_GlobalId, sAppGroupMasterKey0_Key, sAppGroupMasterKey0_KeyLen);
            SuccessOrExit(err);
            break;

        case 2:
            err = AddGroupMasterKey(sAppGroupMasterKey4_Number, sAppGroupMasterKey4_GlobalId, sAppGroupMasterKey4_Key, sAppGroupMasterKey4_KeyLen);
            SuccessOrExit(err);

            err = AddGroupMasterKey(sAppGroupMasterKey7_Number, sAppGroupMasterKey7_GlobalId, sAppGroupMasterKey7_Key, sAppGroupMasterKey7_KeyLen);
            SuccessOrExit(err);

            err = AddGroupMasterKey(sAppGroupMasterKey54_Number, sAppGroupMasterKey54_GlobalId, sAppGroupMasterKey54_Key, sAppGroupMasterKey54_KeyLen);
            SuccessOrExit(err);
            break;

        case 3:
            err = AddGroupMasterKey(sAppGroupMasterKey10_Number, sAppGroupMasterKey10_GlobalId, sAppGroupMasterKey10_Key, sAppGroupMasterKey10_KeyLen);
            SuccessOrExit(err);

            err = AddGroupMasterKey(sAppGroupMasterKey4_Number, sAppGroupMasterKey4_GlobalId, sAppGroupMasterKey4_Key, sAppGroupMasterKey4_KeyLen);
            SuccessOrExit(err);

            err = AddGroupMasterKey(sAppGroupMasterKey7_Number, sAppGroupMasterKey7_GlobalId, sAppGroupMasterKey7_Key, sAppGroupMasterKey7_KeyLen);
            SuccessOrExit(err);

            err = AddGroupMasterKey(sAppGroupMasterKey54_Number, sAppGroupMasterKey54_GlobalId, sAppGroupMasterKey54_Key, sAppGroupMasterKey54_KeyLen);
            SuccessOrExit(err);
            break;

        case 4:
            break;
    }

exit:
    SetDirty(ApplicationKeysTrait::kPropertyHandle_MasterKeys);

    return err;
}

void ApplicationKeysTraitDataSource::ClearEpochKeys(void)
{
    memset(reinterpret_cast<uint8_t *>(&EpochKeys), 0, sizeof(EpochKeys));
}

void ApplicationKeysTraitDataSource::ClearGroupMasterKeys(void)
{
    memset(reinterpret_cast<uint8_t *>(&GroupMasterKeys), 0, sizeof(GroupMasterKeys));
}

WEAVE_ERROR ApplicationKeysTraitDataSource::AddEpochKey(uint8_t epochKeyNumber, uint32_t startTime, const uint8_t *key, uint8_t keyLen)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint32_t keyId = WeaveKeyId::MakeEpochKeyId(epochKeyNumber);
    int keyInd = WEAVE_CONFIG_MAX_APPLICATION_EPOCH_KEYS;

    VerifyOrExit(keyLen <= sizeof(EpochKeys[0].Key), err = WEAVE_ERROR_INVALID_ARGUMENT);

    // Find key entry that stores group epoch key with the same Id (then override the value) or find the first unused key entry.
    for (int i = 0; i < WEAVE_CONFIG_MAX_APPLICATION_EPOCH_KEYS; ++i)
    {
        if (EpochKeys[i].KeyId == keyId)
        {
            keyInd = i;
            break;
        }
        if (keyInd == WEAVE_CONFIG_MAX_APPLICATION_EPOCH_KEYS && EpochKeys[i].KeyId == WeaveKeyId::kNone)
        {
            keyInd = i;
        }
    }

    VerifyOrExit(keyInd < WEAVE_CONFIG_MAX_APPLICATION_EPOCH_KEYS, err = WEAVE_ERROR_NO_MEMORY);

    EpochKeys[keyInd].KeyId = keyId;
    EpochKeys[keyInd].KeyLen = keyLen;
    EpochKeys[keyInd].StartTime = startTime;
    memcpy(EpochKeys[keyInd].Key, key, keyLen);

exit:
    return err;
}

WEAVE_ERROR ApplicationKeysTraitDataSource::AddGroupMasterKey(uint8_t appGroupLocalNumber, uint32_t globalId, const uint8_t *key, uint8_t keyLen)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint32_t keyId = WeaveKeyId::MakeAppGroupMasterKeyId(appGroupLocalNumber);
    int keyInd = WEAVE_CONFIG_MAX_APPLICATION_GROUPS;

    VerifyOrExit(keyLen <= sizeof(GroupMasterKeys[0].Key), err = WEAVE_ERROR_INVALID_ARGUMENT);

    // Find key entry that stores group master key with the same Id (then override the value) or find the first unused key entry.
    for (int i = 0; i < WEAVE_CONFIG_MAX_APPLICATION_GROUPS; ++i)
    {
        if (GroupMasterKeys[i].KeyId == keyId)
        {
            keyInd = i;
            break;
        }
        if (keyInd == WEAVE_CONFIG_MAX_APPLICATION_GROUPS && GroupMasterKeys[i].KeyId == WeaveKeyId::kNone)
        {
            keyInd = i;
        }
    }

    VerifyOrExit(keyInd < WEAVE_CONFIG_MAX_APPLICATION_GROUPS, err = WEAVE_ERROR_NO_MEMORY);

    GroupMasterKeys[keyInd].KeyId = keyId;
    GroupMasterKeys[keyInd].KeyLen = keyLen;
    GroupMasterKeys[keyInd].GlobalId = globalId;
    memcpy(GroupMasterKeys[keyInd].Key, key, keyLen);

exit:
    return err;
}

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

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

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

    if (ApplicationKeysTrait::kPropertyHandle_EpochKeys == aLeafHandle)
    {
        for (int i = 0; i < WEAVE_CONFIG_MAX_APPLICATION_EPOCH_KEYS; ++i)
        {
            if (EpochKeys[i].KeyId != WeaveKeyId::kNone)
            {
                TLVType containerType2;

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

                const uint32_t epochKeyNumber = WeaveKeyId::GetEpochKeyNumber(EpochKeys[i].KeyId);
                err = aWriter.Put(ContextTag(kTag_EpochKey_KeyId), epochKeyNumber);
                SuccessOrExit(err);

                err = aWriter.Put(ContextTag(kTag_EpochKey_StartTime), (static_cast<int64_t>(EpochKeys[i].StartTime) * 1000));
                SuccessOrExit(err);

                err = aWriter.PutBytes(ContextTag(kTag_EpochKey_Key), EpochKeys[i].Key, EpochKeys[i].KeyLen);
                SuccessOrExit(err);

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

                WeaveLogDetail(DataManagement, ">>  GroupEpochKeyId = %08" PRIX32, EpochKeys[i].KeyId);
            }
        }
    }
    else if (ApplicationKeysTrait::kPropertyHandle_MasterKeys == aLeafHandle)
    {
        for (int i = 0; i < WEAVE_CONFIG_MAX_APPLICATION_GROUPS; ++i)
        {
            if (GroupMasterKeys[i].KeyId != WeaveKeyId::kNone)
            {
                TLVType containerType2;

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

                err = aWriter.Put(ContextTag(kTag_ApplicationGroup_GlobalId), GroupMasterKeys[i].GlobalId);
                SuccessOrExit(err);

                const uint32_t appGroupLocalNumber = WeaveKeyId::GetAppGroupLocalNumber(GroupMasterKeys[i].KeyId);
                err = aWriter.Put(ContextTag(kTag_ApplicationGroup_ShortId), appGroupLocalNumber);
                SuccessOrExit(err);

                err = aWriter.PutBytes(ContextTag(kTag_ApplicationGroup_Key), GroupMasterKeys[i].Key, GroupMasterKeys[i].KeyLen);
                SuccessOrExit(err);

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

                WeaveLogDetail(DataManagement, ">>  GroupMasterKeyId = %08" PRIX32, GroupMasterKeys[i].KeyId);
            }
        }
    }
    else
    {
        WeaveLogDetail(DataManagement, "<<  UNKNOWN!");
        ExitNow(err = WEAVE_ERROR_INVALID_TLV_TAG);
    }

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

exit:
    WeaveLogFunctError(err);

    return err;
}

TestCTraitDataSource::TestCTraitDataSource():
#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
        TraitUpdatableDataSource(&TestCTrait::TraitSchema)
#else
        TraitDataSource(&TestCTrait::TraitSchema)
#endif
{
    SetVersion(300);
    taa = true;
    tab = TestCTrait::ENUM_C_VALUE_1;
    tac.scA= 3;
    tac.scB = true;
    tad = 4;
}

void TestCTraitDataSource::Mutate()
{
    Lock();

    if ((GetVersion() % 2) == 0) {
        SetDirty(TestCTrait::kPropertyHandle_TcA);
        taa = !taa;
    }
    else
    {
        SetDirty(TestCTrait::kPropertyHandle_TcC_ScA);
        SetDirty(TestCTrait::kPropertyHandle_TcC_ScB);
        tac.scA ++;
        tac.scB = !tac.scB;
    }

    Unlock();
}

#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
void TestCTraitDataSource::TLVPrettyPrinter(const char *aFormat, ...)
{
    va_list args;

    va_start(args, aFormat);

    vprintf(aFormat, args);

    va_end(args);
}

WEAVE_ERROR
TestCTraitDataSource::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
{

    WEAVE_ERROR err = WEAVE_NO_ERROR;
    switch (aLeafHandle) {
        case TestCTrait::kPropertyHandle_TcA:
            err = aReader.Get(taa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<< taa = %s", taa ? "true" : "false");
            break;
        case TestCTrait::kPropertyHandle_TcB:
            err = aReader.Get(tab);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  tab %d", tab);
            break;
        case TestCTrait::kPropertyHandle_TcC_ScA:
            err = aReader.Get(tac.scA);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  tac.scA %u", tac.scA);
            break;
        case TestCTrait::kPropertyHandle_TcC_ScB:
            err = aReader.Get(tac.scB);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  tac.scB = %s",  tac.scB ? "true" : "false");
            break;
        case TestCTrait::kPropertyHandle_TcD:
            err = aReader.Get(tad);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, "<<  tad %u", tad);
            break;

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

exit:
    return err;
}

#endif // WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT

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

    switch (aLeafHandle) {
        case TestCTrait::kPropertyHandle_TcA:
            err = aWriter.PutBoolean(aTagToWrite, taa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  taa = %s", taa ? "true" : "false");
            break;
        case TestCTrait::kPropertyHandle_TcB:
            err = aWriter.Put(aTagToWrite, tab);
            SuccessOrExit(err);

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

        case TestCTrait::kPropertyHandle_TcC_ScA:
            err = aWriter.Put(aTagToWrite, tac.scA);
            SuccessOrExit(err);

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

        case TestCTrait::kPropertyHandle_TcC_ScB:
            err = aWriter.PutBoolean(aTagToWrite, taa);
            SuccessOrExit(err);

            WeaveLogDetail(DataManagement, ">>  tac.scB = %s",  tac.scB ? "true" : "false");
            break;
        case TestCTrait::kPropertyHandle_TcD:
            err = aWriter.Put(aTagToWrite, tad);
            SuccessOrExit(err);

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

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

exit:
    WeaveLogFunctError(err);

    return err;
}
