/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *
 *    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.
 */

// THIS FILE IS GENERATED BY ZAP
#include "CHIPCallbackTypes.h"

#include <controller/java/AndroidCallbacks.h>
#include <jni.h>
#include <lib/support/ErrorStr.h>
#include <lib/support/JniReferences.h>
#include <zap-generated/CHIPClientCallbacks.h>

class CHIPBooleanAttributeCallback : public chip::Callback::Callback<BooleanAttributeCallback>
{
public:
    CHIPBooleanAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBooleanAttributeCallback();

    static void maybeDestroy(CHIPBooleanAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBooleanAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, bool value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBooleanAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPCharStringAttributeCallback : public chip::Callback::Callback<CharStringAttributeCallback>
{
public:
    CHIPCharStringAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPCharStringAttributeCallback();

    static void maybeDestroy(CHIPCharStringAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPCharStringAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::CharSpan value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPCharStringAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPDoubleAttributeCallback : public chip::Callback::Callback<DoubleAttributeCallback>
{
public:
    CHIPDoubleAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDoubleAttributeCallback();

    static void maybeDestroy(CHIPDoubleAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDoubleAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, double value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDoubleAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPFloatAttributeCallback : public chip::Callback::Callback<FloatAttributeCallback>
{
public:
    CHIPFloatAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFloatAttributeCallback();

    static void maybeDestroy(CHIPFloatAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFloatAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, float value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFloatAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPInt8sAttributeCallback : public chip::Callback::Callback<Int8sAttributeCallback>
{
public:
    CHIPInt8sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPInt8sAttributeCallback();

    static void maybeDestroy(CHIPInt8sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPInt8sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, int8_t value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPInt8sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPInt8uAttributeCallback : public chip::Callback::Callback<Int8uAttributeCallback>
{
public:
    CHIPInt8uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPInt8uAttributeCallback();

    static void maybeDestroy(CHIPInt8uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPInt8uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, uint8_t value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPInt8uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPInt16sAttributeCallback : public chip::Callback::Callback<Int16sAttributeCallback>
{
public:
    CHIPInt16sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPInt16sAttributeCallback();

    static void maybeDestroy(CHIPInt16sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPInt16sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, int16_t value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPInt16sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPInt16uAttributeCallback : public chip::Callback::Callback<Int16uAttributeCallback>
{
public:
    CHIPInt16uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPInt16uAttributeCallback();

    static void maybeDestroy(CHIPInt16uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPInt16uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, uint16_t value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPInt16uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPInt32sAttributeCallback : public chip::Callback::Callback<Int32sAttributeCallback>
{
public:
    CHIPInt32sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPInt32sAttributeCallback();

    static void maybeDestroy(CHIPInt32sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPInt32sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, int32_t value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPInt32sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPInt32uAttributeCallback : public chip::Callback::Callback<Int32uAttributeCallback>
{
public:
    CHIPInt32uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPInt32uAttributeCallback();

    static void maybeDestroy(CHIPInt32uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPInt32uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, uint32_t value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPInt32uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPInt64sAttributeCallback : public chip::Callback::Callback<Int64sAttributeCallback>
{
public:
    CHIPInt64sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPInt64sAttributeCallback();

    static void maybeDestroy(CHIPInt64sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPInt64sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, int64_t value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPInt64sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPInt64uAttributeCallback : public chip::Callback::Callback<Int64uAttributeCallback>
{
public:
    CHIPInt64uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPInt64uAttributeCallback();

    static void maybeDestroy(CHIPInt64uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPInt64uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, uint64_t value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPInt64uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
class CHIPOctetStringAttributeCallback : public chip::Callback::Callback<OctetStringAttributeCallback>
{
public:
    CHIPOctetStringAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOctetStringAttributeCallback();

    static void maybeDestroy(CHIPOctetStringAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOctetStringAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::ByteSpan value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOctetStringAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPIdentifyGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPIdentifyClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPIdentifyGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPIdentifyGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPIdentifyGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPIdentifyGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPIdentifyGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPIdentifyAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPIdentifyClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPIdentifyAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPIdentifyAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPIdentifyAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPIdentifyAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPIdentifyAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPIdentifyAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPIdentifyClusterAttributeListAttributeCallbackType>
{
public:
    CHIPIdentifyAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPIdentifyAttributeListAttributeCallback();

    static void maybeDestroy(CHIPIdentifyAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPIdentifyAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPIdentifyAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGroupsGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPGroupsClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPGroupsGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGroupsGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPGroupsGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGroupsGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGroupsGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGroupsAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPGroupsClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPGroupsAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGroupsAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPGroupsAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGroupsAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGroupsAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGroupsAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPGroupsClusterAttributeListAttributeCallbackType>
{
public:
    CHIPGroupsAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGroupsAttributeListAttributeCallback();

    static void maybeDestroy(CHIPGroupsAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGroupsAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGroupsAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPScenesCurrentGroupAttributeCallback : public chip::Callback::Callback<CHIPScenesClusterCurrentGroupAttributeCallbackType>
{
public:
    CHIPScenesCurrentGroupAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPScenesCurrentGroupAttributeCallback();

    static void maybeDestroy(CHIPScenesCurrentGroupAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPScenesCurrentGroupAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, chip::GroupId value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPScenesCurrentGroupAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPScenesGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPScenesClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPScenesGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPScenesGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPScenesGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPScenesGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPScenesGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPScenesAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPScenesClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPScenesAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPScenesAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPScenesAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPScenesAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPScenesAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPScenesAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPScenesClusterAttributeListAttributeCallbackType>
{
public:
    CHIPScenesAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPScenesAttributeListAttributeCallback();

    static void maybeDestroy(CHIPScenesAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPScenesAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPScenesAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOnOffStartUpOnOffAttributeCallback : public chip::Callback::Callback<CHIPOnOffClusterStartUpOnOffAttributeCallbackType>
{
public:
    CHIPOnOffStartUpOnOffAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOnOffStartUpOnOffAttributeCallback();

    static void maybeDestroy(CHIPOnOffStartUpOnOffAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOnOffStartUpOnOffAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::Nullable<chip::app::Clusters::OnOff::OnOffStartUpOnOff> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOnOffStartUpOnOffAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOnOffGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPOnOffClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPOnOffGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOnOffGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPOnOffGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOnOffGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOnOffGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOnOffAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPOnOffClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPOnOffAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOnOffAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPOnOffAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOnOffAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOnOffAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOnOffAttributeListAttributeCallback : public chip::Callback::Callback<CHIPOnOffClusterAttributeListAttributeCallbackType>
{
public:
    CHIPOnOffAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOnOffAttributeListAttributeCallback();

    static void maybeDestroy(CHIPOnOffAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOnOffAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOnOffAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPOnOffSwitchConfigurationClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPOnOffSwitchConfigurationClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOnOffSwitchConfigurationAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPOnOffSwitchConfigurationClusterAttributeListAttributeCallbackType>
{
public:
    CHIPOnOffSwitchConfigurationAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOnOffSwitchConfigurationAttributeListAttributeCallback();

    static void maybeDestroy(CHIPOnOffSwitchConfigurationAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOnOffSwitchConfigurationAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOnOffSwitchConfigurationAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLevelControlCurrentLevelAttributeCallback
    : public chip::Callback::Callback<CHIPLevelControlClusterCurrentLevelAttributeCallbackType>
{
public:
    CHIPLevelControlCurrentLevelAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLevelControlCurrentLevelAttributeCallback();

    static void maybeDestroy(CHIPLevelControlCurrentLevelAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLevelControlCurrentLevelAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLevelControlCurrentLevelAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLevelControlOnLevelAttributeCallback
    : public chip::Callback::Callback<CHIPLevelControlClusterOnLevelAttributeCallbackType>
{
public:
    CHIPLevelControlOnLevelAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLevelControlOnLevelAttributeCallback();

    static void maybeDestroy(CHIPLevelControlOnLevelAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLevelControlOnLevelAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLevelControlOnLevelAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLevelControlOnTransitionTimeAttributeCallback
    : public chip::Callback::Callback<CHIPLevelControlClusterOnTransitionTimeAttributeCallbackType>
{
public:
    CHIPLevelControlOnTransitionTimeAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLevelControlOnTransitionTimeAttributeCallback();

    static void maybeDestroy(CHIPLevelControlOnTransitionTimeAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLevelControlOnTransitionTimeAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLevelControlOnTransitionTimeAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLevelControlOffTransitionTimeAttributeCallback
    : public chip::Callback::Callback<CHIPLevelControlClusterOffTransitionTimeAttributeCallbackType>
{
public:
    CHIPLevelControlOffTransitionTimeAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLevelControlOffTransitionTimeAttributeCallback();

    static void maybeDestroy(CHIPLevelControlOffTransitionTimeAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLevelControlOffTransitionTimeAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLevelControlOffTransitionTimeAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLevelControlDefaultMoveRateAttributeCallback
    : public chip::Callback::Callback<CHIPLevelControlClusterDefaultMoveRateAttributeCallbackType>
{
public:
    CHIPLevelControlDefaultMoveRateAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLevelControlDefaultMoveRateAttributeCallback();

    static void maybeDestroy(CHIPLevelControlDefaultMoveRateAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLevelControlDefaultMoveRateAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLevelControlDefaultMoveRateAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLevelControlStartUpCurrentLevelAttributeCallback
    : public chip::Callback::Callback<CHIPLevelControlClusterStartUpCurrentLevelAttributeCallbackType>
{
public:
    CHIPLevelControlStartUpCurrentLevelAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLevelControlStartUpCurrentLevelAttributeCallback();

    static void maybeDestroy(CHIPLevelControlStartUpCurrentLevelAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLevelControlStartUpCurrentLevelAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLevelControlStartUpCurrentLevelAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLevelControlGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPLevelControlClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPLevelControlGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLevelControlGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPLevelControlGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLevelControlGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLevelControlGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLevelControlAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPLevelControlClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPLevelControlAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLevelControlAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPLevelControlAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLevelControlAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLevelControlAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLevelControlAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPLevelControlClusterAttributeListAttributeCallbackType>
{
public:
    CHIPLevelControlAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLevelControlAttributeListAttributeCallback();

    static void maybeDestroy(CHIPLevelControlAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLevelControlAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLevelControlAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBinaryInputBasicGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBinaryInputBasicClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPBinaryInputBasicGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBinaryInputBasicGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBinaryInputBasicGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBinaryInputBasicGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBinaryInputBasicGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBinaryInputBasicAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBinaryInputBasicClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPBinaryInputBasicAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBinaryInputBasicAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBinaryInputBasicAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBinaryInputBasicAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBinaryInputBasicAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBinaryInputBasicAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPBinaryInputBasicClusterAttributeListAttributeCallbackType>
{
public:
    CHIPBinaryInputBasicAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBinaryInputBasicAttributeListAttributeCallback();

    static void maybeDestroy(CHIPBinaryInputBasicAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBinaryInputBasicAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBinaryInputBasicAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDescriptorDeviceListAttributeCallback
    : public chip::Callback::Callback<CHIPDescriptorClusterDeviceListAttributeCallbackType>
{
public:
    CHIPDescriptorDeviceListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDescriptorDeviceListAttributeCallback();

    static void maybeDestroy(CHIPDescriptorDeviceListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDescriptorDeviceListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::Descriptor::Structs::DeviceType::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDescriptorDeviceListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDescriptorServerListAttributeCallback
    : public chip::Callback::Callback<CHIPDescriptorClusterServerListAttributeCallbackType>
{
public:
    CHIPDescriptorServerListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDescriptorServerListAttributeCallback();

    static void maybeDestroy(CHIPDescriptorServerListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDescriptorServerListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::ClusterId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDescriptorServerListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDescriptorClientListAttributeCallback
    : public chip::Callback::Callback<CHIPDescriptorClusterClientListAttributeCallbackType>
{
public:
    CHIPDescriptorClientListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDescriptorClientListAttributeCallback();

    static void maybeDestroy(CHIPDescriptorClientListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDescriptorClientListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::ClusterId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDescriptorClientListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDescriptorPartsListAttributeCallback
    : public chip::Callback::Callback<CHIPDescriptorClusterPartsListAttributeCallbackType>
{
public:
    CHIPDescriptorPartsListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDescriptorPartsListAttributeCallback();

    static void maybeDestroy(CHIPDescriptorPartsListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDescriptorPartsListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::EndpointId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDescriptorPartsListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDescriptorGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPDescriptorClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPDescriptorGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDescriptorGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPDescriptorGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDescriptorGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDescriptorGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDescriptorAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPDescriptorClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPDescriptorAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDescriptorAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPDescriptorAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDescriptorAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDescriptorAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDescriptorAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPDescriptorClusterAttributeListAttributeCallbackType>
{
public:
    CHIPDescriptorAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDescriptorAttributeListAttributeCallback();

    static void maybeDestroy(CHIPDescriptorAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDescriptorAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDescriptorAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBindingBindingAttributeCallback : public chip::Callback::Callback<CHIPBindingClusterBindingAttributeCallbackType>
{
public:
    CHIPBindingBindingAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBindingBindingAttributeCallback();

    static void maybeDestroy(CHIPBindingBindingAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBindingBindingAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::Binding::Structs::TargetStruct::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBindingBindingAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBindingGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBindingClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPBindingGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBindingGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBindingGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBindingGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBindingGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBindingAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBindingClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPBindingAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBindingAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBindingAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBindingAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBindingAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBindingAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPBindingClusterAttributeListAttributeCallbackType>
{
public:
    CHIPBindingAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBindingAttributeListAttributeCallback();

    static void maybeDestroy(CHIPBindingAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBindingAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBindingAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAccessControlAclAttributeCallback : public chip::Callback::Callback<CHIPAccessControlClusterAclAttributeCallbackType>
{
public:
    CHIPAccessControlAclAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAccessControlAclAttributeCallback();

    static void maybeDestroy(CHIPAccessControlAclAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAccessControlAclAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::AccessControl::Structs::AccessControlEntry::DecodableType> &
            list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAccessControlAclAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAccessControlExtensionAttributeCallback
    : public chip::Callback::Callback<CHIPAccessControlClusterExtensionAttributeCallbackType>
{
public:
    CHIPAccessControlExtensionAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAccessControlExtensionAttributeCallback();

    static void maybeDestroy(CHIPAccessControlExtensionAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAccessControlExtensionAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::AccessControl::Structs::ExtensionEntry::DecodableType> &
            list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAccessControlExtensionAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAccessControlGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPAccessControlClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPAccessControlGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAccessControlGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPAccessControlGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAccessControlGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAccessControlGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAccessControlAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPAccessControlClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPAccessControlAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAccessControlAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPAccessControlAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAccessControlAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAccessControlAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAccessControlAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPAccessControlClusterAttributeListAttributeCallbackType>
{
public:
    CHIPAccessControlAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAccessControlAttributeListAttributeCallback();

    static void maybeDestroy(CHIPAccessControlAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAccessControlAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAccessControlAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBridgedActionsActionListAttributeCallback
    : public chip::Callback::Callback<CHIPBridgedActionsClusterActionListAttributeCallbackType>
{
public:
    CHIPBridgedActionsActionListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBridgedActionsActionListAttributeCallback();

    static void maybeDestroy(CHIPBridgedActionsActionListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBridgedActionsActionListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::BridgedActions::Structs::ActionStruct::DecodableType> &
            list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBridgedActionsActionListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBridgedActionsEndpointListAttributeCallback
    : public chip::Callback::Callback<CHIPBridgedActionsClusterEndpointListAttributeCallbackType>
{
public:
    CHIPBridgedActionsEndpointListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBridgedActionsEndpointListAttributeCallback();

    static void maybeDestroy(CHIPBridgedActionsEndpointListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBridgedActionsEndpointListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::BridgedActions::Structs::EndpointListStruct::DecodableType> &
            list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBridgedActionsEndpointListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBridgedActionsGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBridgedActionsClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPBridgedActionsGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBridgedActionsGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBridgedActionsGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBridgedActionsGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBridgedActionsGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBridgedActionsAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBridgedActionsClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPBridgedActionsAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBridgedActionsAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBridgedActionsAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBridgedActionsAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBridgedActionsAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBridgedActionsAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPBridgedActionsClusterAttributeListAttributeCallbackType>
{
public:
    CHIPBridgedActionsAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBridgedActionsAttributeListAttributeCallback();

    static void maybeDestroy(CHIPBridgedActionsAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBridgedActionsAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBridgedActionsAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBasicVendorIDAttributeCallback : public chip::Callback::Callback<CHIPBasicClusterVendorIDAttributeCallbackType>
{
public:
    CHIPBasicVendorIDAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBasicVendorIDAttributeCallback();

    static void maybeDestroy(CHIPBasicVendorIDAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBasicVendorIDAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, chip::VendorId value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBasicVendorIDAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBasicGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBasicClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPBasicGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBasicGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBasicGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBasicGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBasicGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBasicAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBasicClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPBasicAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBasicAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBasicAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBasicAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBasicAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBasicAttributeListAttributeCallback : public chip::Callback::Callback<CHIPBasicClusterAttributeListAttributeCallbackType>
{
public:
    CHIPBasicAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBasicAttributeListAttributeCallback();

    static void maybeDestroy(CHIPBasicAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBasicAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBasicAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPOtaSoftwareUpdateProviderClusterAttributeListAttributeCallbackType>
{
public:
    CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback();

    static void maybeDestroy(CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback
    : public chip::Callback::Callback<CHIPOtaSoftwareUpdateRequestorClusterDefaultOtaProvidersAttributeCallbackType>
{
public:
    CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback();

    static void maybeDestroy(CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::DecodableList<
                               chip::app::Clusters::OtaSoftwareUpdateRequestor::Structs::ProviderLocation::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback
    : public chip::Callback::Callback<CHIPOtaSoftwareUpdateRequestorClusterUpdateStateProgressAttributeCallbackType>
{
public:
    CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback();

    static void maybeDestroy(CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPOtaSoftwareUpdateRequestorClusterAttributeListAttributeCallbackType>
{
public:
    CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback();

    static void maybeDestroy(CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLocalizationConfigurationSupportedLocalesAttributeCallback
    : public chip::Callback::Callback<CHIPLocalizationConfigurationClusterSupportedLocalesAttributeCallbackType>
{
public:
    CHIPLocalizationConfigurationSupportedLocalesAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLocalizationConfigurationSupportedLocalesAttributeCallback();

    static void maybeDestroy(CHIPLocalizationConfigurationSupportedLocalesAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLocalizationConfigurationSupportedLocalesAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CharSpan> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLocalizationConfigurationSupportedLocalesAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPLocalizationConfigurationClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPLocalizationConfigurationClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback
    : public chip::Callback::Callback<CHIPTimeFormatLocalizationClusterSupportedCalendarTypesAttributeCallbackType>
{
public:
    CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback();

    static void maybeDestroy(CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback>(callback);
        }
    }

    static void
    CallbackFn(void * context,
               const chip::app::DataModel::DecodableList<chip::app::Clusters::TimeFormatLocalization::CalendarType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPTimeFormatLocalizationClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPTimeFormatLocalizationClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPUnitLocalizationAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPUnitLocalizationClusterAttributeListAttributeCallbackType>
{
public:
    CHIPUnitLocalizationAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPUnitLocalizationAttributeListAttributeCallback();

    static void maybeDestroy(CHIPUnitLocalizationAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPUnitLocalizationAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPUnitLocalizationAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceConfigurationSourcesAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceConfigurationClusterSourcesAttributeCallbackType>
{
public:
    CHIPPowerSourceConfigurationSourcesAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceConfigurationSourcesAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceConfigurationSourcesAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceConfigurationSourcesAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<uint8_t> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceConfigurationSourcesAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceConfigurationClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceConfigurationClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceConfigurationAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceConfigurationClusterAttributeListAttributeCallbackType>
{
public:
    CHIPPowerSourceConfigurationAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceConfigurationAttributeListAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceConfigurationAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceConfigurationAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceConfigurationAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterWiredAssessedInputVoltageAttributeCallbackType>
{
public:
    CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterWiredAssessedInputFrequencyAttributeCallbackType>
{
public:
    CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceWiredAssessedCurrentAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterWiredAssessedCurrentAttributeCallbackType>
{
public:
    CHIPPowerSourceWiredAssessedCurrentAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceWiredAssessedCurrentAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceWiredAssessedCurrentAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceWiredAssessedCurrentAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceWiredAssessedCurrentAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceActiveWiredFaultsAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterActiveWiredFaultsAttributeCallbackType>
{
public:
    CHIPPowerSourceActiveWiredFaultsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceActiveWiredFaultsAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceActiveWiredFaultsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceActiveWiredFaultsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::DecodableList<chip::app::Clusters::PowerSource::WiredFault> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceActiveWiredFaultsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceBatVoltageAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterBatVoltageAttributeCallbackType>
{
public:
    CHIPPowerSourceBatVoltageAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceBatVoltageAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceBatVoltageAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceBatVoltageAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceBatVoltageAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceBatPercentRemainingAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterBatPercentRemainingAttributeCallbackType>
{
public:
    CHIPPowerSourceBatPercentRemainingAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceBatPercentRemainingAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceBatPercentRemainingAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceBatPercentRemainingAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceBatPercentRemainingAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceBatTimeRemainingAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterBatTimeRemainingAttributeCallbackType>
{
public:
    CHIPPowerSourceBatTimeRemainingAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceBatTimeRemainingAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceBatTimeRemainingAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceBatTimeRemainingAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceBatTimeRemainingAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceActiveBatFaultsAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterActiveBatFaultsAttributeCallbackType>
{
public:
    CHIPPowerSourceActiveBatFaultsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceActiveBatFaultsAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceActiveBatFaultsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceActiveBatFaultsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::DecodableList<chip::app::Clusters::PowerSource::BatFault> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceActiveBatFaultsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceBatTimeToFullChargeAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterBatTimeToFullChargeAttributeCallbackType>
{
public:
    CHIPPowerSourceBatTimeToFullChargeAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceBatTimeToFullChargeAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceBatTimeToFullChargeAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceBatTimeToFullChargeAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceBatTimeToFullChargeAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceBatChargingCurrentAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterBatChargingCurrentAttributeCallbackType>
{
public:
    CHIPPowerSourceBatChargingCurrentAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceBatChargingCurrentAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceBatChargingCurrentAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceBatChargingCurrentAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceBatChargingCurrentAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceActiveBatChargeFaultsAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterActiveBatChargeFaultsAttributeCallbackType>
{
public:
    CHIPPowerSourceActiveBatChargeFaultsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceActiveBatChargeFaultsAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceActiveBatChargeFaultsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceActiveBatChargeFaultsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::DecodableList<chip::app::Clusters::PowerSource::BatChargeFault> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceActiveBatChargeFaultsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPPowerSourceGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPPowerSourceAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPowerSourceAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPPowerSourceClusterAttributeListAttributeCallbackType>
{
public:
    CHIPPowerSourceAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPowerSourceAttributeListAttributeCallback();

    static void maybeDestroy(CHIPPowerSourceAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPowerSourceAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPowerSourceAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGeneralCommissioningGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPGeneralCommissioningClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPGeneralCommissioningGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGeneralCommissioningGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPGeneralCommissioningGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGeneralCommissioningGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGeneralCommissioningGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGeneralCommissioningAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPGeneralCommissioningClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPGeneralCommissioningAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGeneralCommissioningAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPGeneralCommissioningAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGeneralCommissioningAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGeneralCommissioningAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGeneralCommissioningAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPGeneralCommissioningClusterAttributeListAttributeCallbackType>
{
public:
    CHIPGeneralCommissioningAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGeneralCommissioningAttributeListAttributeCallback();

    static void maybeDestroy(CHIPGeneralCommissioningAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGeneralCommissioningAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGeneralCommissioningAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPNetworkCommissioningNetworksAttributeCallback
    : public chip::Callback::Callback<CHIPNetworkCommissioningClusterNetworksAttributeCallbackType>
{
public:
    CHIPNetworkCommissioningNetworksAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPNetworkCommissioningNetworksAttributeCallback();

    static void maybeDestroy(CHIPNetworkCommissioningNetworksAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPNetworkCommissioningNetworksAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::NetworkCommissioning::Structs::NetworkInfo::DecodableType> &
            list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPNetworkCommissioningNetworksAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback
    : public chip::Callback::Callback<CHIPNetworkCommissioningClusterLastNetworkingStatusAttributeCallbackType>
{
public:
    CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback();

    static void maybeDestroy(CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback>(callback);
        }
    }

    static void
    CallbackFn(void * context,
               const chip::app::DataModel::Nullable<chip::app::Clusters::NetworkCommissioning::NetworkCommissioningStatus> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPNetworkCommissioningLastNetworkIDAttributeCallback
    : public chip::Callback::Callback<CHIPNetworkCommissioningClusterLastNetworkIDAttributeCallbackType>
{
public:
    CHIPNetworkCommissioningLastNetworkIDAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPNetworkCommissioningLastNetworkIDAttributeCallback();

    static void maybeDestroy(CHIPNetworkCommissioningLastNetworkIDAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPNetworkCommissioningLastNetworkIDAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::ByteSpan> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPNetworkCommissioningLastNetworkIDAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback
    : public chip::Callback::Callback<CHIPNetworkCommissioningClusterLastConnectErrorValueAttributeCallbackType>
{
public:
    CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback();

    static void maybeDestroy(CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPNetworkCommissioningGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPNetworkCommissioningClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPNetworkCommissioningGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPNetworkCommissioningGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPNetworkCommissioningGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPNetworkCommissioningGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPNetworkCommissioningGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPNetworkCommissioningAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPNetworkCommissioningClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPNetworkCommissioningAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPNetworkCommissioningAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPNetworkCommissioningAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPNetworkCommissioningAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPNetworkCommissioningAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDiagnosticLogsGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPDiagnosticLogsClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPDiagnosticLogsGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDiagnosticLogsGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPDiagnosticLogsGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDiagnosticLogsGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDiagnosticLogsGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDiagnosticLogsAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPDiagnosticLogsClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPDiagnosticLogsAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDiagnosticLogsAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPDiagnosticLogsAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDiagnosticLogsAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDiagnosticLogsAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDiagnosticLogsAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPDiagnosticLogsClusterAttributeListAttributeCallbackType>
{
public:
    CHIPDiagnosticLogsAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDiagnosticLogsAttributeListAttributeCallback();

    static void maybeDestroy(CHIPDiagnosticLogsAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDiagnosticLogsAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDiagnosticLogsAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback
    : public chip::Callback::Callback<CHIPGeneralDiagnosticsClusterNetworkInterfacesAttributeCallbackType>
{
public:
    CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback();

    static void maybeDestroy(CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::DecodableList<
                               chip::app::Clusters::GeneralDiagnostics::Structs::NetworkInterfaceType::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback
    : public chip::Callback::Callback<CHIPGeneralDiagnosticsClusterActiveHardwareFaultsAttributeCallbackType>
{
public:
    CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback();

    static void maybeDestroy(CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<uint8_t> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback
    : public chip::Callback::Callback<CHIPGeneralDiagnosticsClusterActiveRadioFaultsAttributeCallbackType>
{
public:
    CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback();

    static void maybeDestroy(CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<uint8_t> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback
    : public chip::Callback::Callback<CHIPGeneralDiagnosticsClusterActiveNetworkFaultsAttributeCallbackType>
{
public:
    CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback();

    static void maybeDestroy(CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<uint8_t> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPGeneralDiagnosticsClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPGeneralDiagnosticsClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGeneralDiagnosticsAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPGeneralDiagnosticsClusterAttributeListAttributeCallbackType>
{
public:
    CHIPGeneralDiagnosticsAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGeneralDiagnosticsAttributeListAttributeCallback();

    static void maybeDestroy(CHIPGeneralDiagnosticsAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGeneralDiagnosticsAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGeneralDiagnosticsAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback
    : public chip::Callback::Callback<CHIPSoftwareDiagnosticsClusterThreadMetricsAttributeCallbackType>
{
public:
    CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback();

    static void maybeDestroy(CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::SoftwareDiagnostics::Structs::ThreadMetrics::DecodableType> &
            list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPSoftwareDiagnosticsClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPSoftwareDiagnosticsClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPSoftwareDiagnosticsAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPSoftwareDiagnosticsClusterAttributeListAttributeCallbackType>
{
public:
    CHIPSoftwareDiagnosticsAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPSoftwareDiagnosticsAttributeListAttributeCallback();

    static void maybeDestroy(CHIPSoftwareDiagnosticsAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPSoftwareDiagnosticsAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPSoftwareDiagnosticsAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsChannelAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterChannelAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsChannelAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsChannelAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsChannelAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsChannelAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsChannelAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback>(callback);
        }
    }

    static void
    CallbackFn(void * context,
               const chip::app::DataModel::Nullable<chip::app::Clusters::ThreadNetworkDiagnostics::RoutingRole> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterNetworkNameAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::CharSpan> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsPanIdAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterPanIdAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsPanIdAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsPanIdAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsPanIdAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsPanIdAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsPanIdAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterExtendedPanIdAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterMeshLocalPrefixAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::ByteSpan> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterNeighborTableListAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::DecodableList<
                               chip::app::Clusters::ThreadNetworkDiagnostics::Structs::NeighborTable::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterRouteTableListAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::DecodableList<
                               chip::app::Clusters::ThreadNetworkDiagnostics::Structs::RouteTable::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterPartitionIdAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsWeightingAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterWeightingAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsWeightingAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsWeightingAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsWeightingAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsWeightingAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsWeightingAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterDataVersionAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterStableDataVersionAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterLeaderRouterIdAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterActiveTimestampAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterPendingTimestampAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsDelayAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterDelayAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsDelayAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsDelayAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsDelayAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsDelayAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsDelayAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsChannelPage0MaskAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterChannelPage0MaskAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsChannelPage0MaskAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsChannelPage0MaskAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsChannelPage0MaskAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsChannelPage0MaskAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::ByteSpan> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsChannelPage0MaskAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterActiveNetworkFaultsListAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback>(callback);
        }
    }

    static void
    CallbackFn(void * context,
               const chip::app::DataModel::DecodableList<chip::app::Clusters::ThreadNetworkDiagnostics::NetworkFault> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterAttributeListAttributeCallbackType>
{
public:
    CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback();

    static void maybeDestroy(CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsBssidAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterBssidAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsBssidAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsBssidAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsBssidAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsBssidAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::ByteSpan> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsBssidAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterSecurityTypeAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::Nullable<chip::app::Clusters::WiFiNetworkDiagnostics::SecurityType> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterWiFiVersionAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback>(callback);
        }
    }

    static void
    CallbackFn(void * context,
               const chip::app::DataModel::Nullable<chip::app::Clusters::WiFiNetworkDiagnostics::WiFiVersionType> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterChannelNumberAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsRssiAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterRssiAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsRssiAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsRssiAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsRssiAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsRssiAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsRssiAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterBeaconLostCountAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterBeaconRxCountAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterPacketMulticastRxCountAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterPacketMulticastTxCountAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterPacketUnicastRxCountAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterPacketUnicastTxCountAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterCurrentMaxRateAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterOverrunCountAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterAttributeListAttributeCallbackType>
{
public:
    CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback();

    static void maybeDestroy(CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback
    : public chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterPHYRateAttributeCallbackType>
{
public:
    CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback();

    static void maybeDestroy(CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback>(callback);
        }
    }

    static void
    CallbackFn(void * context,
               const chip::app::DataModel::Nullable<chip::app::Clusters::EthernetNetworkDiagnostics::PHYRateType> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback
    : public chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterFullDuplexAttributeCallbackType>
{
public:
    CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback();

    static void maybeDestroy(CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<bool> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback
    : public chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterCarrierDetectAttributeCallbackType>
{
public:
    CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback();

    static void maybeDestroy(CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<bool> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterAttributeListAttributeCallbackType>
{
public:
    CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback();

    static void maybeDestroy(CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBridgedDeviceBasicVendorIDAttributeCallback
    : public chip::Callback::Callback<CHIPBridgedDeviceBasicClusterVendorIDAttributeCallbackType>
{
public:
    CHIPBridgedDeviceBasicVendorIDAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBridgedDeviceBasicVendorIDAttributeCallback();

    static void maybeDestroy(CHIPBridgedDeviceBasicVendorIDAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBridgedDeviceBasicVendorIDAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, chip::VendorId value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBridgedDeviceBasicVendorIDAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBridgedDeviceBasicClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBridgedDeviceBasicClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBridgedDeviceBasicAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPBridgedDeviceBasicClusterAttributeListAttributeCallbackType>
{
public:
    CHIPBridgedDeviceBasicAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBridgedDeviceBasicAttributeListAttributeCallback();

    static void maybeDestroy(CHIPBridgedDeviceBasicAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBridgedDeviceBasicAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBridgedDeviceBasicAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPSwitchGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPSwitchClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPSwitchGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPSwitchGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPSwitchGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPSwitchGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPSwitchGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPSwitchAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPSwitchClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPSwitchAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPSwitchAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPSwitchAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPSwitchAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPSwitchAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPSwitchAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPSwitchClusterAttributeListAttributeCallbackType>
{
public:
    CHIPSwitchAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPSwitchAttributeListAttributeCallback();

    static void maybeDestroy(CHIPSwitchAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPSwitchAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPSwitchAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback
    : public chip::Callback::Callback<CHIPAdministratorCommissioningClusterAdminFabricIndexAttributeCallbackType>
{
public:
    CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback();

    static void maybeDestroy(CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::FabricIndex> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAdministratorCommissioningAdminVendorIdAttributeCallback
    : public chip::Callback::Callback<CHIPAdministratorCommissioningClusterAdminVendorIdAttributeCallbackType>
{
public:
    CHIPAdministratorCommissioningAdminVendorIdAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAdministratorCommissioningAdminVendorIdAttributeCallback();

    static void maybeDestroy(CHIPAdministratorCommissioningAdminVendorIdAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAdministratorCommissioningAdminVendorIdAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAdministratorCommissioningAdminVendorIdAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPAdministratorCommissioningClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPAdministratorCommissioningClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAdministratorCommissioningAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPAdministratorCommissioningClusterAttributeListAttributeCallbackType>
{
public:
    CHIPAdministratorCommissioningAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAdministratorCommissioningAttributeListAttributeCallback();

    static void maybeDestroy(CHIPAdministratorCommissioningAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAdministratorCommissioningAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAdministratorCommissioningAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOperationalCredentialsNOCsAttributeCallback
    : public chip::Callback::Callback<CHIPOperationalCredentialsClusterNOCsAttributeCallbackType>
{
public:
    CHIPOperationalCredentialsNOCsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOperationalCredentialsNOCsAttributeCallback();

    static void maybeDestroy(CHIPOperationalCredentialsNOCsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOperationalCredentialsNOCsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::OperationalCredentials::Structs::NOCStruct::DecodableType> &
            list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOperationalCredentialsNOCsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOperationalCredentialsFabricsAttributeCallback
    : public chip::Callback::Callback<CHIPOperationalCredentialsClusterFabricsAttributeCallbackType>
{
public:
    CHIPOperationalCredentialsFabricsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOperationalCredentialsFabricsAttributeCallback();

    static void maybeDestroy(CHIPOperationalCredentialsFabricsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOperationalCredentialsFabricsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::DecodableList<
                               chip::app::Clusters::OperationalCredentials::Structs::FabricDescriptor::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOperationalCredentialsFabricsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback
    : public chip::Callback::Callback<CHIPOperationalCredentialsClusterTrustedRootCertificatesAttributeCallbackType>
{
public:
    CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback();

    static void maybeDestroy(CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::ByteSpan> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOperationalCredentialsGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPOperationalCredentialsClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPOperationalCredentialsGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOperationalCredentialsGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPOperationalCredentialsGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOperationalCredentialsGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOperationalCredentialsGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOperationalCredentialsAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPOperationalCredentialsClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPOperationalCredentialsAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOperationalCredentialsAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPOperationalCredentialsAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOperationalCredentialsAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOperationalCredentialsAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOperationalCredentialsAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPOperationalCredentialsClusterAttributeListAttributeCallbackType>
{
public:
    CHIPOperationalCredentialsAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOperationalCredentialsAttributeListAttributeCallback();

    static void maybeDestroy(CHIPOperationalCredentialsAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOperationalCredentialsAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOperationalCredentialsAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGroupKeyManagementGroupKeyMapAttributeCallback
    : public chip::Callback::Callback<CHIPGroupKeyManagementClusterGroupKeyMapAttributeCallbackType>
{
public:
    CHIPGroupKeyManagementGroupKeyMapAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGroupKeyManagementGroupKeyMapAttributeCallback();

    static void maybeDestroy(CHIPGroupKeyManagementGroupKeyMapAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGroupKeyManagementGroupKeyMapAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::DecodableList<
                               chip::app::Clusters::GroupKeyManagement::Structs::GroupKeyMapStruct::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGroupKeyManagementGroupKeyMapAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGroupKeyManagementGroupTableAttributeCallback
    : public chip::Callback::Callback<CHIPGroupKeyManagementClusterGroupTableAttributeCallbackType>
{
public:
    CHIPGroupKeyManagementGroupTableAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGroupKeyManagementGroupTableAttributeCallback();

    static void maybeDestroy(CHIPGroupKeyManagementGroupTableAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGroupKeyManagementGroupTableAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::DecodableList<
                               chip::app::Clusters::GroupKeyManagement::Structs::GroupInfoMapStruct::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGroupKeyManagementGroupTableAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGroupKeyManagementGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPGroupKeyManagementClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPGroupKeyManagementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGroupKeyManagementGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPGroupKeyManagementGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGroupKeyManagementGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGroupKeyManagementGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGroupKeyManagementAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPGroupKeyManagementClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPGroupKeyManagementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGroupKeyManagementAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPGroupKeyManagementAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGroupKeyManagementAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGroupKeyManagementAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPGroupKeyManagementAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPGroupKeyManagementClusterAttributeListAttributeCallbackType>
{
public:
    CHIPGroupKeyManagementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPGroupKeyManagementAttributeListAttributeCallback();

    static void maybeDestroy(CHIPGroupKeyManagementAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPGroupKeyManagementAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPGroupKeyManagementAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFixedLabelLabelListAttributeCallback
    : public chip::Callback::Callback<CHIPFixedLabelClusterLabelListAttributeCallbackType>
{
public:
    CHIPFixedLabelLabelListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFixedLabelLabelListAttributeCallback();

    static void maybeDestroy(CHIPFixedLabelLabelListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFixedLabelLabelListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::FixedLabel::Structs::LabelStruct::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFixedLabelLabelListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFixedLabelGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPFixedLabelClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPFixedLabelGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFixedLabelGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPFixedLabelGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFixedLabelGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFixedLabelGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFixedLabelAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPFixedLabelClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPFixedLabelAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFixedLabelAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPFixedLabelAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFixedLabelAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFixedLabelAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFixedLabelAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPFixedLabelClusterAttributeListAttributeCallbackType>
{
public:
    CHIPFixedLabelAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFixedLabelAttributeListAttributeCallback();

    static void maybeDestroy(CHIPFixedLabelAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFixedLabelAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFixedLabelAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPUserLabelLabelListAttributeCallback : public chip::Callback::Callback<CHIPUserLabelClusterLabelListAttributeCallbackType>
{
public:
    CHIPUserLabelLabelListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPUserLabelLabelListAttributeCallback();

    static void maybeDestroy(CHIPUserLabelLabelListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPUserLabelLabelListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::UserLabel::Structs::LabelStruct::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPUserLabelLabelListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPUserLabelGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPUserLabelClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPUserLabelGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPUserLabelGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPUserLabelGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPUserLabelGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPUserLabelGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPUserLabelAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPUserLabelClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPUserLabelAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPUserLabelAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPUserLabelAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPUserLabelAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPUserLabelAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBooleanStateGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBooleanStateClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPBooleanStateGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBooleanStateGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBooleanStateGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBooleanStateGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBooleanStateGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBooleanStateAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBooleanStateClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPBooleanStateAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBooleanStateAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBooleanStateAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBooleanStateAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBooleanStateAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBooleanStateAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPBooleanStateClusterAttributeListAttributeCallbackType>
{
public:
    CHIPBooleanStateAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBooleanStateAttributeListAttributeCallback();

    static void maybeDestroy(CHIPBooleanStateAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBooleanStateAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBooleanStateAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPModeSelectStandardNamespaceAttributeCallback
    : public chip::Callback::Callback<CHIPModeSelectClusterStandardNamespaceAttributeCallbackType>
{
public:
    CHIPModeSelectStandardNamespaceAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPModeSelectStandardNamespaceAttributeCallback();

    static void maybeDestroy(CHIPModeSelectStandardNamespaceAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPModeSelectStandardNamespaceAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPModeSelectStandardNamespaceAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPModeSelectSupportedModesAttributeCallback
    : public chip::Callback::Callback<CHIPModeSelectClusterSupportedModesAttributeCallbackType>
{
public:
    CHIPModeSelectSupportedModesAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPModeSelectSupportedModesAttributeCallback();

    static void maybeDestroy(CHIPModeSelectSupportedModesAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPModeSelectSupportedModesAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::ModeSelect::Structs::ModeOptionStruct::DecodableType> &
            list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPModeSelectSupportedModesAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPModeSelectStartUpModeAttributeCallback
    : public chip::Callback::Callback<CHIPModeSelectClusterStartUpModeAttributeCallbackType>
{
public:
    CHIPModeSelectStartUpModeAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPModeSelectStartUpModeAttributeCallback();

    static void maybeDestroy(CHIPModeSelectStartUpModeAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPModeSelectStartUpModeAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPModeSelectStartUpModeAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPModeSelectOnModeAttributeCallback : public chip::Callback::Callback<CHIPModeSelectClusterOnModeAttributeCallbackType>
{
public:
    CHIPModeSelectOnModeAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPModeSelectOnModeAttributeCallback();

    static void maybeDestroy(CHIPModeSelectOnModeAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPModeSelectOnModeAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPModeSelectOnModeAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPModeSelectGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPModeSelectClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPModeSelectGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPModeSelectGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPModeSelectGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPModeSelectGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPModeSelectGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPModeSelectAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPModeSelectClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPModeSelectAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPModeSelectAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPModeSelectAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPModeSelectAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPModeSelectAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPModeSelectAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPModeSelectClusterAttributeListAttributeCallbackType>
{
public:
    CHIPModeSelectAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPModeSelectAttributeListAttributeCallback();

    static void maybeDestroy(CHIPModeSelectAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPModeSelectAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPModeSelectAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDoorLockLockStateAttributeCallback : public chip::Callback::Callback<CHIPDoorLockClusterLockStateAttributeCallbackType>
{
public:
    CHIPDoorLockLockStateAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDoorLockLockStateAttributeCallback();

    static void maybeDestroy(CHIPDoorLockLockStateAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDoorLockLockStateAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlLockState> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDoorLockLockStateAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDoorLockDoorStateAttributeCallback : public chip::Callback::Callback<CHIPDoorLockClusterDoorStateAttributeCallbackType>
{
public:
    CHIPDoorLockDoorStateAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDoorLockDoorStateAttributeCallback();

    static void maybeDestroy(CHIPDoorLockDoorStateAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDoorLockDoorStateAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlDoorState> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDoorLockDoorStateAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDoorLockGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPDoorLockClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPDoorLockGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDoorLockGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPDoorLockGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDoorLockGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDoorLockGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDoorLockAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPDoorLockClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPDoorLockAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDoorLockAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPDoorLockAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDoorLockAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDoorLockAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPDoorLockAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPDoorLockClusterAttributeListAttributeCallbackType>
{
public:
    CHIPDoorLockAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPDoorLockAttributeListAttributeCallback();

    static void maybeDestroy(CHIPDoorLockAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPDoorLockAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPDoorLockAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWindowCoveringCurrentPositionLiftAttributeCallback
    : public chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionLiftAttributeCallbackType>
{
public:
    CHIPWindowCoveringCurrentPositionLiftAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWindowCoveringCurrentPositionLiftAttributeCallback();

    static void maybeDestroy(CHIPWindowCoveringCurrentPositionLiftAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWindowCoveringCurrentPositionLiftAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWindowCoveringCurrentPositionLiftAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWindowCoveringCurrentPositionTiltAttributeCallback
    : public chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionTiltAttributeCallbackType>
{
public:
    CHIPWindowCoveringCurrentPositionTiltAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWindowCoveringCurrentPositionTiltAttributeCallback();

    static void maybeDestroy(CHIPWindowCoveringCurrentPositionTiltAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWindowCoveringCurrentPositionTiltAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWindowCoveringCurrentPositionTiltAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback
    : public chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionLiftPercentageAttributeCallbackType>
{
public:
    CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback();

    static void maybeDestroy(CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::Percent> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback
    : public chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionTiltPercentageAttributeCallbackType>
{
public:
    CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback();

    static void maybeDestroy(CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::Percent> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback
    : public chip::Callback::Callback<CHIPWindowCoveringClusterTargetPositionLiftPercent100thsAttributeCallbackType>
{
public:
    CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback();

    static void maybeDestroy(CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::Percent100ths> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback
    : public chip::Callback::Callback<CHIPWindowCoveringClusterTargetPositionTiltPercent100thsAttributeCallbackType>
{
public:
    CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback();

    static void maybeDestroy(CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::Percent100ths> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback
    : public chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionLiftPercent100thsAttributeCallbackType>
{
public:
    CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback();

    static void maybeDestroy(CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::Percent100ths> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback
    : public chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionTiltPercent100thsAttributeCallbackType>
{
public:
    CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback();

    static void maybeDestroy(CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::Percent100ths> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWindowCoveringGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPWindowCoveringClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPWindowCoveringGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWindowCoveringGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPWindowCoveringGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWindowCoveringGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWindowCoveringGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWindowCoveringAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPWindowCoveringClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPWindowCoveringAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWindowCoveringAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPWindowCoveringAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWindowCoveringAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWindowCoveringAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWindowCoveringAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPWindowCoveringClusterAttributeListAttributeCallbackType>
{
public:
    CHIPWindowCoveringAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWindowCoveringAttributeListAttributeCallback();

    static void maybeDestroy(CHIPWindowCoveringAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWindowCoveringAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWindowCoveringAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBarrierControlGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBarrierControlClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPBarrierControlGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBarrierControlGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBarrierControlGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBarrierControlGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBarrierControlGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBarrierControlAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBarrierControlClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPBarrierControlAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBarrierControlAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBarrierControlAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBarrierControlAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBarrierControlAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBarrierControlAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPBarrierControlClusterAttributeListAttributeCallbackType>
{
public:
    CHIPBarrierControlAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBarrierControlAttributeListAttributeCallback();

    static void maybeDestroy(CHIPBarrierControlAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBarrierControlAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBarrierControlAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMaxPressureAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxPressureAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMaxPressureAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMaxPressureAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMaxPressureAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMaxPressureAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMaxPressureAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxSpeedAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMaxFlowAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxFlowAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMaxFlowAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMaxFlowAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMaxFlowAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMaxFlowAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMaxFlowAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMinConstPressureAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxConstPressureAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMinCompPressureAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxCompPressureAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMinConstSpeedAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxConstSpeedAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMinConstFlowAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxConstFlowAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMinConstTempAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMinConstTempAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMinConstTempAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMinConstTempAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMinConstTempAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMinConstTempAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMinConstTempAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxConstTempAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlCapacityAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterCapacityAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlCapacityAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlCapacityAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlCapacityAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlCapacityAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlCapacityAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlSpeedAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterSpeedAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlSpeedAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlSpeedAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlSpeedAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlSpeedAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlSpeedAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterLifetimeRunningHoursAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlPowerAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterPowerAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlPowerAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlPowerAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlPowerAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlPowerAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlPowerAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterLifetimeEnergyConsumedAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPumpConfigurationAndControlAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterAttributeListAttributeCallbackType>
{
public:
    CHIPPumpConfigurationAndControlAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPumpConfigurationAndControlAttributeListAttributeCallback();

    static void maybeDestroy(CHIPPumpConfigurationAndControlAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPumpConfigurationAndControlAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPumpConfigurationAndControlAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThermostatLocalTemperatureAttributeCallback
    : public chip::Callback::Callback<CHIPThermostatClusterLocalTemperatureAttributeCallbackType>
{
public:
    CHIPThermostatLocalTemperatureAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThermostatLocalTemperatureAttributeCallback();

    static void maybeDestroy(CHIPThermostatLocalTemperatureAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThermostatLocalTemperatureAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThermostatLocalTemperatureAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThermostatAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPThermostatClusterAttributeListAttributeCallbackType>
{
public:
    CHIPThermostatAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThermostatAttributeListAttributeCallback();

    static void maybeDestroy(CHIPThermostatAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThermostatAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThermostatAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFanControlPercentSettingAttributeCallback
    : public chip::Callback::Callback<CHIPFanControlClusterPercentSettingAttributeCallbackType>
{
public:
    CHIPFanControlPercentSettingAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFanControlPercentSettingAttributeCallback();

    static void maybeDestroy(CHIPFanControlPercentSettingAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFanControlPercentSettingAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFanControlPercentSettingAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFanControlSpeedSettingAttributeCallback
    : public chip::Callback::Callback<CHIPFanControlClusterSpeedSettingAttributeCallbackType>
{
public:
    CHIPFanControlSpeedSettingAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFanControlSpeedSettingAttributeCallback();

    static void maybeDestroy(CHIPFanControlSpeedSettingAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFanControlSpeedSettingAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFanControlSpeedSettingAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFanControlGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPFanControlClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPFanControlGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFanControlGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPFanControlGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFanControlGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFanControlGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFanControlAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPFanControlClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPFanControlAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFanControlAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPFanControlAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFanControlAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFanControlAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFanControlAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPFanControlClusterAttributeListAttributeCallbackType>
{
public:
    CHIPFanControlAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFanControlAttributeListAttributeCallback();

    static void maybeDestroy(CHIPFanControlAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFanControlAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFanControlAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPThermostatUserInterfaceConfigurationClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback *>(context)
                ->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPThermostatUserInterfaceConfigurationClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback *>(context)
                ->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPThermostatUserInterfaceConfigurationClusterAttributeListAttributeCallbackType>
{
public:
    CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback();

    static void maybeDestroy(CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlNumberOfPrimariesAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterNumberOfPrimariesAttributeCallbackType>
{
public:
    CHIPColorControlNumberOfPrimariesAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlNumberOfPrimariesAttributeCallback();

    static void maybeDestroy(CHIPColorControlNumberOfPrimariesAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlNumberOfPrimariesAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlNumberOfPrimariesAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlPrimary1IntensityAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterPrimary1IntensityAttributeCallbackType>
{
public:
    CHIPColorControlPrimary1IntensityAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlPrimary1IntensityAttributeCallback();

    static void maybeDestroy(CHIPColorControlPrimary1IntensityAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlPrimary1IntensityAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlPrimary1IntensityAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlPrimary2IntensityAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterPrimary2IntensityAttributeCallbackType>
{
public:
    CHIPColorControlPrimary2IntensityAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlPrimary2IntensityAttributeCallback();

    static void maybeDestroy(CHIPColorControlPrimary2IntensityAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlPrimary2IntensityAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlPrimary2IntensityAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlPrimary3IntensityAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterPrimary3IntensityAttributeCallbackType>
{
public:
    CHIPColorControlPrimary3IntensityAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlPrimary3IntensityAttributeCallback();

    static void maybeDestroy(CHIPColorControlPrimary3IntensityAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlPrimary3IntensityAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlPrimary3IntensityAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlPrimary4IntensityAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterPrimary4IntensityAttributeCallbackType>
{
public:
    CHIPColorControlPrimary4IntensityAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlPrimary4IntensityAttributeCallback();

    static void maybeDestroy(CHIPColorControlPrimary4IntensityAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlPrimary4IntensityAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlPrimary4IntensityAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlPrimary5IntensityAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterPrimary5IntensityAttributeCallbackType>
{
public:
    CHIPColorControlPrimary5IntensityAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlPrimary5IntensityAttributeCallback();

    static void maybeDestroy(CHIPColorControlPrimary5IntensityAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlPrimary5IntensityAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlPrimary5IntensityAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlPrimary6IntensityAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterPrimary6IntensityAttributeCallbackType>
{
public:
    CHIPColorControlPrimary6IntensityAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlPrimary6IntensityAttributeCallback();

    static void maybeDestroy(CHIPColorControlPrimary6IntensityAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlPrimary6IntensityAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlPrimary6IntensityAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlColorPointRIntensityAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterColorPointRIntensityAttributeCallbackType>
{
public:
    CHIPColorControlColorPointRIntensityAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlColorPointRIntensityAttributeCallback();

    static void maybeDestroy(CHIPColorControlColorPointRIntensityAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlColorPointRIntensityAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlColorPointRIntensityAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlColorPointGIntensityAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterColorPointGIntensityAttributeCallbackType>
{
public:
    CHIPColorControlColorPointGIntensityAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlColorPointGIntensityAttributeCallback();

    static void maybeDestroy(CHIPColorControlColorPointGIntensityAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlColorPointGIntensityAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlColorPointGIntensityAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlColorPointBIntensityAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterColorPointBIntensityAttributeCallbackType>
{
public:
    CHIPColorControlColorPointBIntensityAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlColorPointBIntensityAttributeCallback();

    static void maybeDestroy(CHIPColorControlColorPointBIntensityAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlColorPointBIntensityAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlColorPointBIntensityAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPColorControlGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPColorControlGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPColorControlAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPColorControlAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPColorControlAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPColorControlClusterAttributeListAttributeCallbackType>
{
public:
    CHIPColorControlAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPColorControlAttributeListAttributeCallback();

    static void maybeDestroy(CHIPColorControlAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPColorControlAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPColorControlAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback
    : public chip::Callback::Callback<CHIPBallastConfigurationClusterIntrinsicBalanceFactorAttributeCallbackType>
{
public:
    CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback();

    static void maybeDestroy(CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback
    : public chip::Callback::Callback<CHIPBallastConfigurationClusterBallastFactorAdjustmentAttributeCallbackType>
{
public:
    CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback();

    static void maybeDestroy(CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBallastConfigurationLampRatedHoursAttributeCallback
    : public chip::Callback::Callback<CHIPBallastConfigurationClusterLampRatedHoursAttributeCallbackType>
{
public:
    CHIPBallastConfigurationLampRatedHoursAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBallastConfigurationLampRatedHoursAttributeCallback();

    static void maybeDestroy(CHIPBallastConfigurationLampRatedHoursAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBallastConfigurationLampRatedHoursAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBallastConfigurationLampRatedHoursAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBallastConfigurationLampBurnHoursAttributeCallback
    : public chip::Callback::Callback<CHIPBallastConfigurationClusterLampBurnHoursAttributeCallbackType>
{
public:
    CHIPBallastConfigurationLampBurnHoursAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBallastConfigurationLampBurnHoursAttributeCallback();

    static void maybeDestroy(CHIPBallastConfigurationLampBurnHoursAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBallastConfigurationLampBurnHoursAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBallastConfigurationLampBurnHoursAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback
    : public chip::Callback::Callback<CHIPBallastConfigurationClusterLampBurnHoursTripPointAttributeCallbackType>
{
public:
    CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback();

    static void maybeDestroy(CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBallastConfigurationGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBallastConfigurationClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPBallastConfigurationGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBallastConfigurationGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBallastConfigurationGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBallastConfigurationGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBallastConfigurationGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBallastConfigurationAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPBallastConfigurationClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPBallastConfigurationAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBallastConfigurationAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPBallastConfigurationAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBallastConfigurationAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBallastConfigurationAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPBallastConfigurationAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPBallastConfigurationClusterAttributeListAttributeCallbackType>
{
public:
    CHIPBallastConfigurationAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPBallastConfigurationAttributeListAttributeCallback();

    static void maybeDestroy(CHIPBallastConfigurationAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPBallastConfigurationAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPBallastConfigurationAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPIlluminanceMeasurementMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPIlluminanceMeasurementClusterMeasuredValueAttributeCallbackType>
{
public:
    CHIPIlluminanceMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPIlluminanceMeasurementMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPIlluminanceMeasurementMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPIlluminanceMeasurementMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPIlluminanceMeasurementMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPIlluminanceMeasurementClusterMinMeasuredValueAttributeCallbackType>
{
public:
    CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPIlluminanceMeasurementClusterMaxMeasuredValueAttributeCallbackType>
{
public:
    CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback
    : public chip::Callback::Callback<CHIPIlluminanceMeasurementClusterLightSensorTypeAttributeCallbackType>
{
public:
    CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback();

    static void maybeDestroy(CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPIlluminanceMeasurementClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPIlluminanceMeasurementClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPIlluminanceMeasurementAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPIlluminanceMeasurementClusterAttributeListAttributeCallbackType>
{
public:
    CHIPIlluminanceMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPIlluminanceMeasurementAttributeListAttributeCallback();

    static void maybeDestroy(CHIPIlluminanceMeasurementAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPIlluminanceMeasurementAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPIlluminanceMeasurementAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTemperatureMeasurementMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPTemperatureMeasurementClusterMeasuredValueAttributeCallbackType>
{
public:
    CHIPTemperatureMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTemperatureMeasurementMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPTemperatureMeasurementMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTemperatureMeasurementMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTemperatureMeasurementMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPTemperatureMeasurementClusterMinMeasuredValueAttributeCallbackType>
{
public:
    CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPTemperatureMeasurementClusterMaxMeasuredValueAttributeCallbackType>
{
public:
    CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTemperatureMeasurementAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPTemperatureMeasurementClusterAttributeListAttributeCallbackType>
{
public:
    CHIPTemperatureMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTemperatureMeasurementAttributeListAttributeCallback();

    static void maybeDestroy(CHIPTemperatureMeasurementAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTemperatureMeasurementAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTemperatureMeasurementAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPressureMeasurementMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPPressureMeasurementClusterMeasuredValueAttributeCallbackType>
{
public:
    CHIPPressureMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPressureMeasurementMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPPressureMeasurementMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPressureMeasurementMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPressureMeasurementMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPressureMeasurementMinMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPPressureMeasurementClusterMinMeasuredValueAttributeCallbackType>
{
public:
    CHIPPressureMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPressureMeasurementMinMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPPressureMeasurementMinMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPressureMeasurementMinMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPressureMeasurementMinMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPressureMeasurementMaxMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPPressureMeasurementClusterMaxMeasuredValueAttributeCallbackType>
{
public:
    CHIPPressureMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPressureMeasurementMaxMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPPressureMeasurementMaxMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPressureMeasurementMaxMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPressureMeasurementMaxMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPressureMeasurementScaledValueAttributeCallback
    : public chip::Callback::Callback<CHIPPressureMeasurementClusterScaledValueAttributeCallbackType>
{
public:
    CHIPPressureMeasurementScaledValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPressureMeasurementScaledValueAttributeCallback();

    static void maybeDestroy(CHIPPressureMeasurementScaledValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPressureMeasurementScaledValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPressureMeasurementScaledValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPressureMeasurementMinScaledValueAttributeCallback
    : public chip::Callback::Callback<CHIPPressureMeasurementClusterMinScaledValueAttributeCallbackType>
{
public:
    CHIPPressureMeasurementMinScaledValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPressureMeasurementMinScaledValueAttributeCallback();

    static void maybeDestroy(CHIPPressureMeasurementMinScaledValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPressureMeasurementMinScaledValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPressureMeasurementMinScaledValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPressureMeasurementMaxScaledValueAttributeCallback
    : public chip::Callback::Callback<CHIPPressureMeasurementClusterMaxScaledValueAttributeCallbackType>
{
public:
    CHIPPressureMeasurementMaxScaledValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPressureMeasurementMaxScaledValueAttributeCallback();

    static void maybeDestroy(CHIPPressureMeasurementMaxScaledValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPressureMeasurementMaxScaledValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPressureMeasurementMaxScaledValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPPressureMeasurementAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPPressureMeasurementClusterAttributeListAttributeCallbackType>
{
public:
    CHIPPressureMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPPressureMeasurementAttributeListAttributeCallback();

    static void maybeDestroy(CHIPPressureMeasurementAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPPressureMeasurementAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPPressureMeasurementAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFlowMeasurementMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPFlowMeasurementClusterMeasuredValueAttributeCallbackType>
{
public:
    CHIPFlowMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFlowMeasurementMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPFlowMeasurementMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFlowMeasurementMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFlowMeasurementMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFlowMeasurementMinMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPFlowMeasurementClusterMinMeasuredValueAttributeCallbackType>
{
public:
    CHIPFlowMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFlowMeasurementMinMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPFlowMeasurementMinMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFlowMeasurementMinMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFlowMeasurementMinMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFlowMeasurementMaxMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPFlowMeasurementClusterMaxMeasuredValueAttributeCallbackType>
{
public:
    CHIPFlowMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFlowMeasurementMaxMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPFlowMeasurementMaxMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFlowMeasurementMaxMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFlowMeasurementMaxMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFlowMeasurementGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPFlowMeasurementClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPFlowMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFlowMeasurementGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPFlowMeasurementGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFlowMeasurementGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFlowMeasurementGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFlowMeasurementAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPFlowMeasurementClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPFlowMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFlowMeasurementAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPFlowMeasurementAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFlowMeasurementAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFlowMeasurementAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPFlowMeasurementAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPFlowMeasurementClusterAttributeListAttributeCallbackType>
{
public:
    CHIPFlowMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPFlowMeasurementAttributeListAttributeCallback();

    static void maybeDestroy(CHIPFlowMeasurementAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPFlowMeasurementAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPFlowMeasurementAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterMeasuredValueAttributeCallbackType>
{
public:
    CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterMinMeasuredValueAttributeCallbackType>
{
public:
    CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback
    : public chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterMaxMeasuredValueAttributeCallbackType>
{
public:
    CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback();

    static void maybeDestroy(CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPRelativeHumidityMeasurementAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterAttributeListAttributeCallbackType>
{
public:
    CHIPRelativeHumidityMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPRelativeHumidityMeasurementAttributeListAttributeCallback();

    static void maybeDestroy(CHIPRelativeHumidityMeasurementAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPRelativeHumidityMeasurementAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPRelativeHumidityMeasurementAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOccupancySensingGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPOccupancySensingClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPOccupancySensingGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOccupancySensingGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPOccupancySensingGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOccupancySensingGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOccupancySensingGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOccupancySensingAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPOccupancySensingClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPOccupancySensingAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOccupancySensingAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPOccupancySensingAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOccupancySensingAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOccupancySensingAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPOccupancySensingAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPOccupancySensingClusterAttributeListAttributeCallbackType>
{
public:
    CHIPOccupancySensingAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPOccupancySensingAttributeListAttributeCallback();

    static void maybeDestroy(CHIPOccupancySensingAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPOccupancySensingAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPOccupancySensingAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWakeOnLanGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPWakeOnLanClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPWakeOnLanGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWakeOnLanGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPWakeOnLanGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWakeOnLanGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWakeOnLanGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWakeOnLanAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPWakeOnLanClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPWakeOnLanAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWakeOnLanAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPWakeOnLanAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWakeOnLanAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWakeOnLanAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPWakeOnLanAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPWakeOnLanClusterAttributeListAttributeCallbackType>
{
public:
    CHIPWakeOnLanAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPWakeOnLanAttributeListAttributeCallback();

    static void maybeDestroy(CHIPWakeOnLanAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPWakeOnLanAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPWakeOnLanAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPChannelChannelListAttributeCallback : public chip::Callback::Callback<CHIPChannelClusterChannelListAttributeCallbackType>
{
public:
    CHIPChannelChannelListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPChannelChannelListAttributeCallback();

    static void maybeDestroy(CHIPChannelChannelListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPChannelChannelListAttributeCallback>(callback);
        }
    }

    static void
    CallbackFn(void * context,
               const chip::app::DataModel::DecodableList<chip::app::Clusters::Channel::Structs::ChannelInfo::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPChannelChannelListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPChannelGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPChannelClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPChannelGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPChannelGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPChannelGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPChannelGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPChannelGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPChannelAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPChannelClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPChannelAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPChannelAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPChannelAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPChannelAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPChannelAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPChannelAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPChannelClusterAttributeListAttributeCallbackType>
{
public:
    CHIPChannelAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPChannelAttributeListAttributeCallback();

    static void maybeDestroy(CHIPChannelAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPChannelAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPChannelAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTargetNavigatorTargetListAttributeCallback
    : public chip::Callback::Callback<CHIPTargetNavigatorClusterTargetListAttributeCallbackType>
{
public:
    CHIPTargetNavigatorTargetListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTargetNavigatorTargetListAttributeCallback();

    static void maybeDestroy(CHIPTargetNavigatorTargetListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTargetNavigatorTargetListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::TargetNavigator::Structs::TargetInfo::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTargetNavigatorTargetListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTargetNavigatorGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPTargetNavigatorClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPTargetNavigatorGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTargetNavigatorGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPTargetNavigatorGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTargetNavigatorGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTargetNavigatorGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTargetNavigatorAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPTargetNavigatorClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPTargetNavigatorAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTargetNavigatorAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPTargetNavigatorAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTargetNavigatorAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTargetNavigatorAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTargetNavigatorAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPTargetNavigatorClusterAttributeListAttributeCallbackType>
{
public:
    CHIPTargetNavigatorAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTargetNavigatorAttributeListAttributeCallback();

    static void maybeDestroy(CHIPTargetNavigatorAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTargetNavigatorAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTargetNavigatorAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPMediaPlaybackStartTimeAttributeCallback
    : public chip::Callback::Callback<CHIPMediaPlaybackClusterStartTimeAttributeCallbackType>
{
public:
    CHIPMediaPlaybackStartTimeAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPMediaPlaybackStartTimeAttributeCallback();

    static void maybeDestroy(CHIPMediaPlaybackStartTimeAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPMediaPlaybackStartTimeAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPMediaPlaybackStartTimeAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPMediaPlaybackDurationAttributeCallback
    : public chip::Callback::Callback<CHIPMediaPlaybackClusterDurationAttributeCallbackType>
{
public:
    CHIPMediaPlaybackDurationAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPMediaPlaybackDurationAttributeCallback();

    static void maybeDestroy(CHIPMediaPlaybackDurationAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPMediaPlaybackDurationAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPMediaPlaybackDurationAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPMediaPlaybackSeekRangeEndAttributeCallback
    : public chip::Callback::Callback<CHIPMediaPlaybackClusterSeekRangeEndAttributeCallbackType>
{
public:
    CHIPMediaPlaybackSeekRangeEndAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPMediaPlaybackSeekRangeEndAttributeCallback();

    static void maybeDestroy(CHIPMediaPlaybackSeekRangeEndAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPMediaPlaybackSeekRangeEndAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPMediaPlaybackSeekRangeEndAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPMediaPlaybackSeekRangeStartAttributeCallback
    : public chip::Callback::Callback<CHIPMediaPlaybackClusterSeekRangeStartAttributeCallbackType>
{
public:
    CHIPMediaPlaybackSeekRangeStartAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPMediaPlaybackSeekRangeStartAttributeCallback();

    static void maybeDestroy(CHIPMediaPlaybackSeekRangeStartAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPMediaPlaybackSeekRangeStartAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPMediaPlaybackSeekRangeStartAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPMediaPlaybackGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPMediaPlaybackClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPMediaPlaybackGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPMediaPlaybackGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPMediaPlaybackGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPMediaPlaybackGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPMediaPlaybackGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPMediaPlaybackAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPMediaPlaybackClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPMediaPlaybackAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPMediaPlaybackAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPMediaPlaybackAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPMediaPlaybackAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPMediaPlaybackAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPMediaPlaybackAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPMediaPlaybackClusterAttributeListAttributeCallbackType>
{
public:
    CHIPMediaPlaybackAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPMediaPlaybackAttributeListAttributeCallback();

    static void maybeDestroy(CHIPMediaPlaybackAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPMediaPlaybackAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPMediaPlaybackAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPMediaInputInputListAttributeCallback
    : public chip::Callback::Callback<CHIPMediaInputClusterInputListAttributeCallbackType>
{
public:
    CHIPMediaInputInputListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPMediaInputInputListAttributeCallback();

    static void maybeDestroy(CHIPMediaInputInputListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPMediaInputInputListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::MediaInput::Structs::InputInfo::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPMediaInputInputListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPMediaInputGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPMediaInputClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPMediaInputGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPMediaInputGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPMediaInputGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPMediaInputGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPMediaInputGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPMediaInputAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPMediaInputClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPMediaInputAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPMediaInputAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPMediaInputAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPMediaInputAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPMediaInputAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPMediaInputAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPMediaInputClusterAttributeListAttributeCallbackType>
{
public:
    CHIPMediaInputAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPMediaInputAttributeListAttributeCallback();

    static void maybeDestroy(CHIPMediaInputAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPMediaInputAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPMediaInputAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLowPowerGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPLowPowerClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPLowPowerGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLowPowerGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPLowPowerGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLowPowerGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLowPowerGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLowPowerAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPLowPowerClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPLowPowerAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLowPowerAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPLowPowerAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLowPowerAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLowPowerAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPLowPowerAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPLowPowerClusterAttributeListAttributeCallbackType>
{
public:
    CHIPLowPowerAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPLowPowerAttributeListAttributeCallback();

    static void maybeDestroy(CHIPLowPowerAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPLowPowerAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPLowPowerAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPKeypadInputGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPKeypadInputClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPKeypadInputGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPKeypadInputGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPKeypadInputGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPKeypadInputGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPKeypadInputGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPKeypadInputAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPKeypadInputClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPKeypadInputAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPKeypadInputAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPKeypadInputAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPKeypadInputAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPKeypadInputAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPKeypadInputAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPKeypadInputClusterAttributeListAttributeCallbackType>
{
public:
    CHIPKeypadInputAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPKeypadInputAttributeListAttributeCallback();

    static void maybeDestroy(CHIPKeypadInputAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPKeypadInputAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPKeypadInputAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPContentLauncherAcceptHeaderAttributeCallback
    : public chip::Callback::Callback<CHIPContentLauncherClusterAcceptHeaderAttributeCallbackType>
{
public:
    CHIPContentLauncherAcceptHeaderAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPContentLauncherAcceptHeaderAttributeCallback();

    static void maybeDestroy(CHIPContentLauncherAcceptHeaderAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPContentLauncherAcceptHeaderAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CharSpan> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPContentLauncherAcceptHeaderAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPContentLauncherGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPContentLauncherClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPContentLauncherGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPContentLauncherGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPContentLauncherGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPContentLauncherGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPContentLauncherGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPContentLauncherAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPContentLauncherClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPContentLauncherAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPContentLauncherAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPContentLauncherAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPContentLauncherAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPContentLauncherAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPContentLauncherAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPContentLauncherClusterAttributeListAttributeCallbackType>
{
public:
    CHIPContentLauncherAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPContentLauncherAttributeListAttributeCallback();

    static void maybeDestroy(CHIPContentLauncherAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPContentLauncherAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPContentLauncherAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAudioOutputOutputListAttributeCallback
    : public chip::Callback::Callback<CHIPAudioOutputClusterOutputListAttributeCallbackType>
{
public:
    CHIPAudioOutputOutputListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAudioOutputOutputListAttributeCallback();

    static void maybeDestroy(CHIPAudioOutputOutputListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAudioOutputOutputListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::AudioOutput::Structs::OutputInfo::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAudioOutputOutputListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAudioOutputGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPAudioOutputClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPAudioOutputGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAudioOutputGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPAudioOutputGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAudioOutputGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAudioOutputGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAudioOutputAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPAudioOutputClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPAudioOutputAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAudioOutputAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPAudioOutputAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAudioOutputAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAudioOutputAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAudioOutputAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPAudioOutputClusterAttributeListAttributeCallbackType>
{
public:
    CHIPAudioOutputAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAudioOutputAttributeListAttributeCallback();

    static void maybeDestroy(CHIPAudioOutputAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAudioOutputAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAudioOutputAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPApplicationLauncherCatalogListAttributeCallback
    : public chip::Callback::Callback<CHIPApplicationLauncherClusterCatalogListAttributeCallbackType>
{
public:
    CHIPApplicationLauncherCatalogListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPApplicationLauncherCatalogListAttributeCallback();

    static void maybeDestroy(CHIPApplicationLauncherCatalogListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPApplicationLauncherCatalogListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<uint16_t> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPApplicationLauncherCatalogListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPApplicationLauncherGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPApplicationLauncherClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPApplicationLauncherGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPApplicationLauncherGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPApplicationLauncherGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPApplicationLauncherGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPApplicationLauncherGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPApplicationLauncherAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPApplicationLauncherClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPApplicationLauncherAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPApplicationLauncherAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPApplicationLauncherAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPApplicationLauncherAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPApplicationLauncherAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPApplicationLauncherAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPApplicationLauncherClusterAttributeListAttributeCallbackType>
{
public:
    CHIPApplicationLauncherAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPApplicationLauncherAttributeListAttributeCallback();

    static void maybeDestroy(CHIPApplicationLauncherAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPApplicationLauncherAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPApplicationLauncherAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPApplicationBasicVendorIDAttributeCallback
    : public chip::Callback::Callback<CHIPApplicationBasicClusterVendorIDAttributeCallbackType>
{
public:
    CHIPApplicationBasicVendorIDAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPApplicationBasicVendorIDAttributeCallback();

    static void maybeDestroy(CHIPApplicationBasicVendorIDAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPApplicationBasicVendorIDAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, chip::VendorId value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPApplicationBasicVendorIDAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPApplicationBasicAllowedVendorListAttributeCallback
    : public chip::Callback::Callback<CHIPApplicationBasicClusterAllowedVendorListAttributeCallbackType>
{
public:
    CHIPApplicationBasicAllowedVendorListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPApplicationBasicAllowedVendorListAttributeCallback();

    static void maybeDestroy(CHIPApplicationBasicAllowedVendorListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPApplicationBasicAllowedVendorListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::VendorId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPApplicationBasicAllowedVendorListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPApplicationBasicGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPApplicationBasicClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPApplicationBasicGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPApplicationBasicGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPApplicationBasicGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPApplicationBasicGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPApplicationBasicGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPApplicationBasicAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPApplicationBasicClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPApplicationBasicAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPApplicationBasicAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPApplicationBasicAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPApplicationBasicAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPApplicationBasicAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPApplicationBasicAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPApplicationBasicClusterAttributeListAttributeCallbackType>
{
public:
    CHIPApplicationBasicAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPApplicationBasicAttributeListAttributeCallback();

    static void maybeDestroy(CHIPApplicationBasicAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPApplicationBasicAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPApplicationBasicAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAccountLoginGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPAccountLoginClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPAccountLoginGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAccountLoginGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPAccountLoginGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAccountLoginGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAccountLoginGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAccountLoginAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPAccountLoginClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPAccountLoginAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAccountLoginAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPAccountLoginAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAccountLoginAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAccountLoginAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPAccountLoginAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPAccountLoginClusterAttributeListAttributeCallbackType>
{
public:
    CHIPAccountLoginAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPAccountLoginAttributeListAttributeCallback();

    static void maybeDestroy(CHIPAccountLoginAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPAccountLoginAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPAccountLoginAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPElectricalMeasurementGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPElectricalMeasurementClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPElectricalMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPElectricalMeasurementGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPElectricalMeasurementGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPElectricalMeasurementGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPElectricalMeasurementGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPElectricalMeasurementAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPElectricalMeasurementClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPElectricalMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPElectricalMeasurementAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPElectricalMeasurementAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPElectricalMeasurementAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPElectricalMeasurementAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPElectricalMeasurementAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPElectricalMeasurementClusterAttributeListAttributeCallbackType>
{
public:
    CHIPElectricalMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPElectricalMeasurementAttributeListAttributeCallback();

    static void maybeDestroy(CHIPElectricalMeasurementAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPElectricalMeasurementAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPElectricalMeasurementAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterListInt8uAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterListInt8uAttributeCallbackType>
{
public:
    CHIPTestClusterListInt8uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterListInt8uAttributeCallback();

    static void maybeDestroy(CHIPTestClusterListInt8uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterListInt8uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<uint8_t> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterListInt8uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterListOctetStringAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterListOctetStringAttributeCallbackType>
{
public:
    CHIPTestClusterListOctetStringAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterListOctetStringAttributeCallback();

    static void maybeDestroy(CHIPTestClusterListOctetStringAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterListOctetStringAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::ByteSpan> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterListOctetStringAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterListStructOctetStringAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterListStructOctetStringAttributeCallbackType>
{
public:
    CHIPTestClusterListStructOctetStringAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterListStructOctetStringAttributeCallback();

    static void maybeDestroy(CHIPTestClusterListStructOctetStringAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterListStructOctetStringAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::TestCluster::Structs::TestListStructOctet::DecodableType> &
            list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterListStructOctetStringAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterVendorIdAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterVendorIdAttributeCallbackType>
{
public:
    CHIPTestClusterVendorIdAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterVendorIdAttributeCallback();

    static void maybeDestroy(CHIPTestClusterVendorIdAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterVendorIdAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, chip::VendorId value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterVendorIdAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterListNullablesAndOptionalsStructAttributeCallbackType>
{
public:
    CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback();

    static void maybeDestroy(CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::DecodableList<
                               chip::app::Clusters::TestCluster::Structs::NullablesAndOptionalsStruct::DecodableType> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterListLongOctetStringAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterListLongOctetStringAttributeCallbackType>
{
public:
    CHIPTestClusterListLongOctetStringAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterListLongOctetStringAttributeCallback();

    static void maybeDestroy(CHIPTestClusterListLongOctetStringAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterListLongOctetStringAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::ByteSpan> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterListLongOctetStringAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterListFabricScopedAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterListFabricScopedAttributeCallbackType>
{
public:
    CHIPTestClusterListFabricScopedAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterListFabricScopedAttributeCallback();

    static void maybeDestroy(CHIPTestClusterListFabricScopedAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterListFabricScopedAttributeCallback>(callback);
        }
    }

    static void CallbackFn(
        void * context,
        const chip::app::DataModel::DecodableList<chip::app::Clusters::TestCluster::Structs::TestFabricScoped::DecodableType> &
            list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterListFabricScopedAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableBooleanAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableBooleanAttributeCallbackType>
{
public:
    CHIPTestClusterNullableBooleanAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableBooleanAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableBooleanAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableBooleanAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<bool> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableBooleanAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableBitmap8AttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableBitmap8AttributeCallbackType>
{
public:
    CHIPTestClusterNullableBitmap8AttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableBitmap8AttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableBitmap8AttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableBitmap8AttributeCallback>(callback);
        }
    }

    static void
    CallbackFn(void * context,
               const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap>> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableBitmap8AttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableBitmap16AttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableBitmap16AttributeCallbackType>
{
public:
    CHIPTestClusterNullableBitmap16AttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableBitmap16AttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableBitmap16AttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableBitmap16AttributeCallback>(callback);
        }
    }

    static void
    CallbackFn(void * context,
               const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap>> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableBitmap16AttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableBitmap32AttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableBitmap32AttributeCallbackType>
{
public:
    CHIPTestClusterNullableBitmap32AttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableBitmap32AttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableBitmap32AttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableBitmap32AttributeCallback>(callback);
        }
    }

    static void
    CallbackFn(void * context,
               const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap>> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableBitmap32AttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableBitmap64AttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableBitmap64AttributeCallbackType>
{
public:
    CHIPTestClusterNullableBitmap64AttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableBitmap64AttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableBitmap64AttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableBitmap64AttributeCallback>(callback);
        }
    }

    static void
    CallbackFn(void * context,
               const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap>> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableBitmap64AttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt8uAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt8uAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt8uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt8uAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt8uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt8uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt8uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt16uAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt16uAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt16uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt16uAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt16uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt16uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt16uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt24uAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt24uAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt24uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt24uAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt24uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt24uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt24uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt32uAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt32uAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt32uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt32uAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt32uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt32uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt32uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt40uAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt40uAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt40uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt40uAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt40uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt40uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt40uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt48uAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt48uAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt48uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt48uAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt48uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt48uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt48uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt56uAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt56uAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt56uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt56uAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt56uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt56uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt56uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt64uAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt64uAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt64uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt64uAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt64uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt64uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt64uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt8sAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt8sAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt8sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt8sAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt8sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt8sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt8sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt16sAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt16sAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt16sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt16sAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt16sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt16sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt16sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt24sAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt24sAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt24sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt24sAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt24sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt24sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt24sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt32sAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt32sAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt32sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt32sAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt32sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt32sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int32_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt32sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt40sAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt40sAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt40sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt40sAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt40sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt40sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt40sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt48sAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt48sAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt48sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt48sAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt48sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt48sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt48sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt56sAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt56sAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt56sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt56sAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt56sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt56sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt56sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableInt64sAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableInt64sAttributeCallbackType>
{
public:
    CHIPTestClusterNullableInt64sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableInt64sAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableInt64sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableInt64sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int64_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableInt64sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableEnum8AttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableEnum8AttributeCallbackType>
{
public:
    CHIPTestClusterNullableEnum8AttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableEnum8AttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableEnum8AttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableEnum8AttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableEnum8AttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableEnum16AttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableEnum16AttributeCallbackType>
{
public:
    CHIPTestClusterNullableEnum16AttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableEnum16AttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableEnum16AttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableEnum16AttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableEnum16AttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableFloatSingleAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableFloatSingleAttributeCallbackType>
{
public:
    CHIPTestClusterNullableFloatSingleAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableFloatSingleAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableFloatSingleAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableFloatSingleAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<float> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableFloatSingleAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableFloatDoubleAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableFloatDoubleAttributeCallbackType>
{
public:
    CHIPTestClusterNullableFloatDoubleAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableFloatDoubleAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableFloatDoubleAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableFloatDoubleAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<double> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableFloatDoubleAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableOctetStringAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableOctetStringAttributeCallbackType>
{
public:
    CHIPTestClusterNullableOctetStringAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableOctetStringAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableOctetStringAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableOctetStringAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::ByteSpan> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableOctetStringAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableCharStringAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableCharStringAttributeCallbackType>
{
public:
    CHIPTestClusterNullableCharStringAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableCharStringAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableCharStringAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableCharStringAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<chip::CharSpan> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableCharStringAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableEnumAttrAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableEnumAttrAttributeCallbackType>
{
public:
    CHIPTestClusterNullableEnumAttrAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableEnumAttrAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableEnumAttrAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableEnumAttrAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context,
                           const chip::app::DataModel::Nullable<chip::app::Clusters::TestCluster::SimpleEnum> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableEnumAttrAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableRangeRestrictedInt8uAttributeCallbackType>
{
public:
    CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableRangeRestrictedInt8sAttributeCallbackType>
{
public:
    CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int8_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableRangeRestrictedInt16uAttributeCallbackType>
{
public:
    CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterNullableRangeRestrictedInt16sAttributeCallbackType>
{
public:
    CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback();

    static void maybeDestroy(CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterGeneratedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterGeneratedCommandListAttributeCallbackType>
{
public:
    CHIPTestClusterGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterGeneratedCommandListAttributeCallback();

    static void maybeDestroy(CHIPTestClusterGeneratedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterGeneratedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterGeneratedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterAcceptedCommandListAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterAcceptedCommandListAttributeCallbackType>
{
public:
    CHIPTestClusterAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterAcceptedCommandListAttributeCallback();

    static void maybeDestroy(CHIPTestClusterAcceptedCommandListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterAcceptedCommandListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterAcceptedCommandListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

class CHIPTestClusterAttributeListAttributeCallback
    : public chip::Callback::Callback<CHIPTestClusterClusterAttributeListAttributeCallbackType>
{
public:
    CHIPTestClusterAttributeListAttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIPTestClusterAttributeListAttributeCallback();

    static void maybeDestroy(CHIPTestClusterAttributeListAttributeCallback * callback)
    {
        if (!callback->keepAlive)
        {
            callback->Cancel();
            chip::Platform::Delete<CHIPTestClusterAttributeListAttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list);
    static void OnSubscriptionEstablished(void * context)
    {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(
            reinterpret_cast<CHIPTestClusterAttributeListAttributeCallback *>(context)->javaCallbackRef);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
