/*
 *
 *    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 "CHIPReadCallbacks.h"

#include <zap-generated/CHIPClientCallbacks.h>

#include <jni.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/JniReferences.h>
#include <lib/support/JniTypeWrappers.h>
#include <platform/PlatformManager.h>

CHIPBooleanAttributeCallback::CHIPBooleanAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<BooleanAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBooleanAttributeCallback::~CHIPBooleanAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBooleanAttributeCallback::CallbackFn(void * context, bool value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBooleanAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBooleanAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Z)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
    env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<jboolean>(value));
}

CHIPCharStringAttributeCallback::CHIPCharStringAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CharStringAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCharStringAttributeCallback::~CHIPCharStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCharStringAttributeCallback::CallbackFn(void * context, const chip::CharSpan value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPCharStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCharStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;

    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/String;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));

    chip::UtfString valueStr(env, value);
    env->CallVoidMethod(javaCallbackRef, javaMethod, valueStr.jniValue());
}

CHIPDoubleAttributeCallback::CHIPDoubleAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<DoubleAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDoubleAttributeCallback::~CHIPDoubleAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDoubleAttributeCallback::CallbackFn(void * context, double value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDoubleAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDoubleAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(D)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
    env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<jdouble>(value));
}

CHIPFloatAttributeCallback::CHIPFloatAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<FloatAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFloatAttributeCallback::~CHIPFloatAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFloatAttributeCallback::CallbackFn(void * context, float value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFloatAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFloatAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(F)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
    env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<jfloat>(value));
}

CHIPInt8sAttributeCallback::CHIPInt8sAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<Int8sAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInt8sAttributeCallback::~CHIPInt8sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInt8sAttributeCallback::CallbackFn(void * context, int8_t value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPInt8sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInt8sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(I)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
    env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<jint>(value));
}

CHIPInt8uAttributeCallback::CHIPInt8uAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<Int8uAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInt8uAttributeCallback::~CHIPInt8uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInt8uAttributeCallback::CallbackFn(void * context, uint8_t value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPInt8uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInt8uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(I)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
    env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<jint>(value));
}

CHIPInt16sAttributeCallback::CHIPInt16sAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<Int16sAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInt16sAttributeCallback::~CHIPInt16sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInt16sAttributeCallback::CallbackFn(void * context, int16_t value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPInt16sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInt16sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(I)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
    env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<jint>(value));
}

CHIPInt16uAttributeCallback::CHIPInt16uAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<Int16uAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInt16uAttributeCallback::~CHIPInt16uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInt16uAttributeCallback::CallbackFn(void * context, uint16_t value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPInt16uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInt16uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(I)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
    env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<jint>(value));
}

CHIPInt32sAttributeCallback::CHIPInt32sAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<Int32sAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInt32sAttributeCallback::~CHIPInt32sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInt32sAttributeCallback::CallbackFn(void * context, int32_t value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPInt32sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInt32sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(J)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
    env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<jlong>(value));
}

CHIPInt32uAttributeCallback::CHIPInt32uAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<Int32uAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInt32uAttributeCallback::~CHIPInt32uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInt32uAttributeCallback::CallbackFn(void * context, uint32_t value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPInt32uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInt32uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(J)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
    env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<jlong>(value));
}

CHIPInt64sAttributeCallback::CHIPInt64sAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<Int64sAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInt64sAttributeCallback::~CHIPInt64sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInt64sAttributeCallback::CallbackFn(void * context, int64_t value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPInt64sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInt64sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(J)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
    env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<jlong>(value));
}

CHIPInt64uAttributeCallback::CHIPInt64uAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<Int64uAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInt64uAttributeCallback::~CHIPInt64uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInt64uAttributeCallback::CallbackFn(void * context, uint64_t value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPInt64uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInt64uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(J)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
    env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<jlong>(value));
}

CHIPOctetStringAttributeCallback::CHIPOctetStringAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<OctetStringAttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }
    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOctetStringAttributeCallback::~CHIPOctetStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOctetStringAttributeCallback::CallbackFn(void * context, const chip::ByteSpan value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;

    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOctetStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOctetStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;

    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "([B)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));

    jbyteArray valueArr = env->NewByteArray(value.size());
    env->ExceptionClear();
    env->SetByteArrayRegion(valueArr, 0, value.size(), reinterpret_cast<const jbyte *>(value.data()));

    env->CallVoidMethod(javaCallbackRef, javaMethod, valueArr);
}

CHIPIdentifyGeneratedCommandListAttributeCallback::CHIPIdentifyGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPIdentifyClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIdentifyGeneratedCommandListAttributeCallback::~CHIPIdentifyGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIdentifyGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPIdentifyGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIdentifyGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPIdentifyAcceptedCommandListAttributeCallback::CHIPIdentifyAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPIdentifyClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIdentifyAcceptedCommandListAttributeCallback::~CHIPIdentifyAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIdentifyAcceptedCommandListAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPIdentifyAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIdentifyAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPIdentifyAttributeListAttributeCallback::CHIPIdentifyAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPIdentifyClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIdentifyAttributeListAttributeCallback::~CHIPIdentifyAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIdentifyAttributeListAttributeCallback::CallbackFn(void * context,
                                                            const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPIdentifyAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIdentifyAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGroupsGeneratedCommandListAttributeCallback::CHIPGroupsGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPGroupsClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGroupsGeneratedCommandListAttributeCallback::~CHIPGroupsGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGroupsGeneratedCommandListAttributeCallback::CallbackFn(void * context,
                                                                 const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGroupsGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGroupsGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGroupsAcceptedCommandListAttributeCallback::CHIPGroupsAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPGroupsClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGroupsAcceptedCommandListAttributeCallback::~CHIPGroupsAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGroupsAcceptedCommandListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGroupsAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGroupsAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGroupsAttributeListAttributeCallback::CHIPGroupsAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPGroupsClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGroupsAttributeListAttributeCallback::~CHIPGroupsAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGroupsAttributeListAttributeCallback::CallbackFn(void * context,
                                                          const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGroupsAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGroupsAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPScenesCurrentGroupAttributeCallback::CHIPScenesCurrentGroupAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPScenesClusterCurrentGroupAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPScenesCurrentGroupAttributeCallback::~CHIPScenesCurrentGroupAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPScenesCurrentGroupAttributeCallback::CallbackFn(void * context, chip::GroupId value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPScenesCurrentGroupAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPScenesCurrentGroupAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    std::string javaValueClassName     = "java/lang/Integer";
    std::string javaValueCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                   value, javaValue);

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPScenesGeneratedCommandListAttributeCallback::CHIPScenesGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPScenesClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPScenesGeneratedCommandListAttributeCallback::~CHIPScenesGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPScenesGeneratedCommandListAttributeCallback::CallbackFn(void * context,
                                                                 const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPScenesGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPScenesGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPScenesAcceptedCommandListAttributeCallback::CHIPScenesAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPScenesClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPScenesAcceptedCommandListAttributeCallback::~CHIPScenesAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPScenesAcceptedCommandListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPScenesAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPScenesAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPScenesAttributeListAttributeCallback::CHIPScenesAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPScenesClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPScenesAttributeListAttributeCallback::~CHIPScenesAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPScenesAttributeListAttributeCallback::CallbackFn(void * context,
                                                          const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPScenesAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPScenesAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOnOffStartUpOnOffAttributeCallback::CHIPOnOffStartUpOnOffAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOnOffClusterStartUpOnOffAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOnOffStartUpOnOffAttributeCallback::~CHIPOnOffStartUpOnOffAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOnOffStartUpOnOffAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::app::Clusters::OnOff::OnOffStartUpOnOff> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPOnOffStartUpOnOffAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOnOffStartUpOnOffAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(value.Value()), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPOnOffGeneratedCommandListAttributeCallback::CHIPOnOffGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPOnOffClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOnOffGeneratedCommandListAttributeCallback::~CHIPOnOffGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOnOffGeneratedCommandListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOnOffGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOnOffGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOnOffAcceptedCommandListAttributeCallback::CHIPOnOffAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOnOffClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOnOffAcceptedCommandListAttributeCallback::~CHIPOnOffAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOnOffAcceptedCommandListAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOnOffAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOnOffAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOnOffAttributeListAttributeCallback::CHIPOnOffAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOnOffClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOnOffAttributeListAttributeCallback::~CHIPOnOffAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOnOffAttributeListAttributeCallback::CallbackFn(void * context,
                                                         const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOnOffAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOnOffAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback::
    CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOnOffSwitchConfigurationClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback::
    ~CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOnOffSwitchConfigurationGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback::CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOnOffSwitchConfigurationClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback::
    ~CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOnOffSwitchConfigurationAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOnOffSwitchConfigurationAttributeListAttributeCallback::CHIPOnOffSwitchConfigurationAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOnOffSwitchConfigurationClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOnOffSwitchConfigurationAttributeListAttributeCallback::~CHIPOnOffSwitchConfigurationAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOnOffSwitchConfigurationAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOnOffSwitchConfigurationAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOnOffSwitchConfigurationAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLevelControlCurrentLevelAttributeCallback::CHIPLevelControlCurrentLevelAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLevelControlClusterCurrentLevelAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLevelControlCurrentLevelAttributeCallback::~CHIPLevelControlCurrentLevelAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLevelControlCurrentLevelAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPLevelControlCurrentLevelAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLevelControlCurrentLevelAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPLevelControlOnLevelAttributeCallback::CHIPLevelControlOnLevelAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLevelControlClusterOnLevelAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLevelControlOnLevelAttributeCallback::~CHIPLevelControlOnLevelAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLevelControlOnLevelAttributeCallback::CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPLevelControlOnLevelAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLevelControlOnLevelAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPLevelControlOnTransitionTimeAttributeCallback::CHIPLevelControlOnTransitionTimeAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPLevelControlClusterOnTransitionTimeAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLevelControlOnTransitionTimeAttributeCallback::~CHIPLevelControlOnTransitionTimeAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLevelControlOnTransitionTimeAttributeCallback::CallbackFn(void * context,
                                                                   const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPLevelControlOnTransitionTimeAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLevelControlOnTransitionTimeAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPLevelControlOffTransitionTimeAttributeCallback::CHIPLevelControlOffTransitionTimeAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPLevelControlClusterOffTransitionTimeAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLevelControlOffTransitionTimeAttributeCallback::~CHIPLevelControlOffTransitionTimeAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLevelControlOffTransitionTimeAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPLevelControlOffTransitionTimeAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLevelControlOffTransitionTimeAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPLevelControlDefaultMoveRateAttributeCallback::CHIPLevelControlDefaultMoveRateAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPLevelControlClusterDefaultMoveRateAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLevelControlDefaultMoveRateAttributeCallback::~CHIPLevelControlDefaultMoveRateAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLevelControlDefaultMoveRateAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPLevelControlDefaultMoveRateAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLevelControlDefaultMoveRateAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPLevelControlStartUpCurrentLevelAttributeCallback::CHIPLevelControlStartUpCurrentLevelAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPLevelControlClusterStartUpCurrentLevelAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLevelControlStartUpCurrentLevelAttributeCallback::~CHIPLevelControlStartUpCurrentLevelAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLevelControlStartUpCurrentLevelAttributeCallback::CallbackFn(void * context,
                                                                      const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPLevelControlStartUpCurrentLevelAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLevelControlStartUpCurrentLevelAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPLevelControlGeneratedCommandListAttributeCallback::CHIPLevelControlGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPLevelControlClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLevelControlGeneratedCommandListAttributeCallback::~CHIPLevelControlGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLevelControlGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPLevelControlGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLevelControlGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLevelControlAcceptedCommandListAttributeCallback::CHIPLevelControlAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPLevelControlClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLevelControlAcceptedCommandListAttributeCallback::~CHIPLevelControlAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLevelControlAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPLevelControlAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLevelControlAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLevelControlAttributeListAttributeCallback::CHIPLevelControlAttributeListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPLevelControlClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLevelControlAttributeListAttributeCallback::~CHIPLevelControlAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLevelControlAttributeListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPLevelControlAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLevelControlAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBinaryInputBasicGeneratedCommandListAttributeCallback::CHIPBinaryInputBasicGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBinaryInputBasicClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBinaryInputBasicGeneratedCommandListAttributeCallback::~CHIPBinaryInputBasicGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBinaryInputBasicGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBinaryInputBasicGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBinaryInputBasicGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBinaryInputBasicAcceptedCommandListAttributeCallback::CHIPBinaryInputBasicAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBinaryInputBasicClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBinaryInputBasicAcceptedCommandListAttributeCallback::~CHIPBinaryInputBasicAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBinaryInputBasicAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBinaryInputBasicAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBinaryInputBasicAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBinaryInputBasicAttributeListAttributeCallback::CHIPBinaryInputBasicAttributeListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPBinaryInputBasicClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBinaryInputBasicAttributeListAttributeCallback::~CHIPBinaryInputBasicAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBinaryInputBasicAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBinaryInputBasicAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBinaryInputBasicAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDescriptorDeviceListAttributeCallback::CHIPDescriptorDeviceListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDescriptorClusterDeviceListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDescriptorDeviceListAttributeCallback::~CHIPDescriptorDeviceListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDescriptorDeviceListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::Descriptor::Structs::DeviceType::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDescriptorDeviceListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDescriptorDeviceListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_type;
        std::string newElement_0_typeClassName     = "java/lang/Long";
        std::string newElement_0_typeCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
            newElement_0_typeClassName.c_str(), newElement_0_typeCtorSignature.c_str(), entry_0.type, newElement_0_type);
        jobject newElement_0_revision;
        std::string newElement_0_revisionClassName     = "java/lang/Integer";
        std::string newElement_0_revisionCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_revisionClassName.c_str(),
                                                                       newElement_0_revisionCtorSignature.c_str(), entry_0.revision,
                                                                       newElement_0_revision);

        jclass deviceTypeStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs$DescriptorClusterDeviceType",
                                                             deviceTypeStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$DescriptorClusterDeviceType");
            return;
        }
        jmethodID deviceTypeStructCtor_1 =
            env->GetMethodID(deviceTypeStructClass_1, "<init>", "(Ljava/lang/Long;Ljava/lang/Integer;)V");
        if (deviceTypeStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$DescriptorClusterDeviceType constructor");
            return;
        }

        newElement_0 = env->NewObject(deviceTypeStructClass_1, deviceTypeStructCtor_1, newElement_0_type, newElement_0_revision);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDescriptorServerListAttributeCallback::CHIPDescriptorServerListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDescriptorClusterServerListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDescriptorServerListAttributeCallback::~CHIPDescriptorServerListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDescriptorServerListAttributeCallback::CallbackFn(void * context,
                                                           const chip::app::DataModel::DecodableList<chip::ClusterId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDescriptorServerListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDescriptorServerListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDescriptorClientListAttributeCallback::CHIPDescriptorClientListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDescriptorClusterClientListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDescriptorClientListAttributeCallback::~CHIPDescriptorClientListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDescriptorClientListAttributeCallback::CallbackFn(void * context,
                                                           const chip::app::DataModel::DecodableList<chip::ClusterId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDescriptorClientListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDescriptorClientListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDescriptorPartsListAttributeCallback::CHIPDescriptorPartsListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDescriptorClusterPartsListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDescriptorPartsListAttributeCallback::~CHIPDescriptorPartsListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDescriptorPartsListAttributeCallback::CallbackFn(void * context,
                                                          const chip::app::DataModel::DecodableList<chip::EndpointId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDescriptorPartsListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDescriptorPartsListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDescriptorGeneratedCommandListAttributeCallback::CHIPDescriptorGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPDescriptorClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDescriptorGeneratedCommandListAttributeCallback::~CHIPDescriptorGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDescriptorGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDescriptorGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDescriptorGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDescriptorAcceptedCommandListAttributeCallback::CHIPDescriptorAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPDescriptorClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDescriptorAcceptedCommandListAttributeCallback::~CHIPDescriptorAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDescriptorAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDescriptorAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDescriptorAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDescriptorAttributeListAttributeCallback::CHIPDescriptorAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDescriptorClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDescriptorAttributeListAttributeCallback::~CHIPDescriptorAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDescriptorAttributeListAttributeCallback::CallbackFn(void * context,
                                                              const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDescriptorAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDescriptorAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBindingBindingAttributeCallback::CHIPBindingBindingAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBindingClusterBindingAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBindingBindingAttributeCallback::~CHIPBindingBindingAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBindingBindingAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::Binding::Structs::TargetStruct::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBindingBindingAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBindingBindingAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_node;
        if (!entry_0.node.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_node);
        }
        else
        {
            jobject newElement_0_nodeInsideOptional;
            std::string newElement_0_nodeInsideOptionalClassName     = "java/lang/Long";
            std::string newElement_0_nodeInsideOptionalCtorSignature = "(J)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_0_nodeInsideOptionalClassName.c_str(),
                                                                           newElement_0_nodeInsideOptionalCtorSignature.c_str(),
                                                                           entry_0.node.Value(), newElement_0_nodeInsideOptional);
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_nodeInsideOptional, newElement_0_node);
        }
        jobject newElement_0_group;
        if (!entry_0.group.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_group);
        }
        else
        {
            jobject newElement_0_groupInsideOptional;
            std::string newElement_0_groupInsideOptionalClassName     = "java/lang/Integer";
            std::string newElement_0_groupInsideOptionalCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_groupInsideOptionalClassName.c_str(),
                                                                           newElement_0_groupInsideOptionalCtorSignature.c_str(),
                                                                           entry_0.group.Value(), newElement_0_groupInsideOptional);
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_groupInsideOptional, newElement_0_group);
        }
        jobject newElement_0_endpoint;
        if (!entry_0.endpoint.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_endpoint);
        }
        else
        {
            jobject newElement_0_endpointInsideOptional;
            std::string newElement_0_endpointInsideOptionalClassName     = "java/lang/Integer";
            std::string newElement_0_endpointInsideOptionalCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
                newElement_0_endpointInsideOptionalClassName.c_str(), newElement_0_endpointInsideOptionalCtorSignature.c_str(),
                entry_0.endpoint.Value(), newElement_0_endpointInsideOptional);
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_endpointInsideOptional, newElement_0_endpoint);
        }
        jobject newElement_0_cluster;
        if (!entry_0.cluster.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_cluster);
        }
        else
        {
            jobject newElement_0_clusterInsideOptional;
            std::string newElement_0_clusterInsideOptionalClassName     = "java/lang/Long";
            std::string newElement_0_clusterInsideOptionalCtorSignature = "(J)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
                newElement_0_clusterInsideOptionalClassName.c_str(), newElement_0_clusterInsideOptionalCtorSignature.c_str(),
                entry_0.cluster.Value(), newElement_0_clusterInsideOptional);
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_clusterInsideOptional, newElement_0_cluster);
        }
        jobject newElement_0_fabricIndex;
        std::string newElement_0_fabricIndexClassName     = "java/lang/Integer";
        std::string newElement_0_fabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_fabricIndexClassName.c_str(),
                                                                      newElement_0_fabricIndexCtorSignature.c_str(),
                                                                      entry_0.fabricIndex, newElement_0_fabricIndex);

        jclass targetStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs$BindingClusterTargetStruct",
                                                             targetStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$BindingClusterTargetStruct");
            return;
        }
        jmethodID targetStructStructCtor_1 = env->GetMethodID(
            targetStructStructClass_1, "<init>",
            "(Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;Ljava/lang/Integer;)V");
        if (targetStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$BindingClusterTargetStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(targetStructStructClass_1, targetStructStructCtor_1, newElement_0_node, newElement_0_group,
                                      newElement_0_endpoint, newElement_0_cluster, newElement_0_fabricIndex);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBindingGeneratedCommandListAttributeCallback::CHIPBindingGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPBindingClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBindingGeneratedCommandListAttributeCallback::~CHIPBindingGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBindingGeneratedCommandListAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBindingGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBindingGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBindingAcceptedCommandListAttributeCallback::CHIPBindingAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPBindingClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBindingAcceptedCommandListAttributeCallback::~CHIPBindingAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBindingAcceptedCommandListAttributeCallback::CallbackFn(void * context,
                                                                 const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBindingAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBindingAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBindingAttributeListAttributeCallback::CHIPBindingAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBindingClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBindingAttributeListAttributeCallback::~CHIPBindingAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBindingAttributeListAttributeCallback::CallbackFn(void * context,
                                                           const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBindingAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBindingAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAccessControlAclAttributeCallback::CHIPAccessControlAclAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAccessControlClusterAclAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAccessControlAclAttributeCallback::~CHIPAccessControlAclAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAccessControlAclAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::AccessControl::Structs::AccessControlEntry::DecodableType> &
        list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAccessControlAclAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAccessControlAclAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_privilege;
        std::string newElement_0_privilegeClassName     = "java/lang/Integer";
        std::string newElement_0_privilegeCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_privilegeClassName.c_str(), newElement_0_privilegeCtorSignature.c_str(),
            static_cast<uint8_t>(entry_0.privilege), newElement_0_privilege);
        jobject newElement_0_authMode;
        std::string newElement_0_authModeClassName     = "java/lang/Integer";
        std::string newElement_0_authModeCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_authModeClassName.c_str(), newElement_0_authModeCtorSignature.c_str(),
            static_cast<uint8_t>(entry_0.authMode), newElement_0_authMode);
        jobject newElement_0_subjects;
        if (entry_0.subjects.IsNull())
        {
            newElement_0_subjects = nullptr;
        }
        else
        {
            chip::JniReferences::GetInstance().CreateArrayList(newElement_0_subjects);

            auto iter_newElement_0_subjects_3 = entry_0.subjects.Value().begin();
            while (iter_newElement_0_subjects_3.Next())
            {
                auto & entry_3 = iter_newElement_0_subjects_3.GetValue();
                jobject newElement_3;
                std::string newElement_3ClassName     = "java/lang/Long";
                std::string newElement_3CtorSignature = "(J)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(
                    newElement_3ClassName.c_str(), newElement_3CtorSignature.c_str(), entry_3, newElement_3);
                chip::JniReferences::GetInstance().AddToList(newElement_0_subjects, newElement_3);
            }
        }
        jobject newElement_0_targets;
        if (entry_0.targets.IsNull())
        {
            newElement_0_targets = nullptr;
        }
        else
        {
            chip::JniReferences::GetInstance().CreateArrayList(newElement_0_targets);

            auto iter_newElement_0_targets_3 = entry_0.targets.Value().begin();
            while (iter_newElement_0_targets_3.Next())
            {
                auto & entry_3 = iter_newElement_0_targets_3.GetValue();
                jobject newElement_3;
                jobject newElement_3_cluster;
                if (entry_3.cluster.IsNull())
                {
                    newElement_3_cluster = nullptr;
                }
                else
                {
                    std::string newElement_3_clusterClassName     = "java/lang/Long";
                    std::string newElement_3_clusterCtorSignature = "(J)V";
                    chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_3_clusterClassName.c_str(),
                                                                                   newElement_3_clusterCtorSignature.c_str(),
                                                                                   entry_3.cluster.Value(), newElement_3_cluster);
                }
                jobject newElement_3_endpoint;
                if (entry_3.endpoint.IsNull())
                {
                    newElement_3_endpoint = nullptr;
                }
                else
                {
                    std::string newElement_3_endpointClassName     = "java/lang/Integer";
                    std::string newElement_3_endpointCtorSignature = "(I)V";
                    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_3_endpointClassName.c_str(),
                                                                                   newElement_3_endpointCtorSignature.c_str(),
                                                                                   entry_3.endpoint.Value(), newElement_3_endpoint);
                }
                jobject newElement_3_deviceType;
                if (entry_3.deviceType.IsNull())
                {
                    newElement_3_deviceType = nullptr;
                }
                else
                {
                    std::string newElement_3_deviceTypeClassName     = "java/lang/Long";
                    std::string newElement_3_deviceTypeCtorSignature = "(J)V";
                    chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
                        newElement_3_deviceTypeClassName.c_str(), newElement_3_deviceTypeCtorSignature.c_str(),
                        entry_3.deviceType.Value(), newElement_3_deviceType);
                }

                jclass targetStructClass_4;
                err = chip::JniReferences::GetInstance().GetClassRef(
                    env, "chip/devicecontroller/ChipStructs$AccessControlClusterTarget", targetStructClass_4);
                if (err != CHIP_NO_ERROR)
                {
                    ChipLogError(Zcl, "Could not find class ChipStructs$AccessControlClusterTarget");
                    return;
                }
                jmethodID targetStructCtor_4 =
                    env->GetMethodID(targetStructClass_4, "<init>", "(Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Long;)V");
                if (targetStructCtor_4 == nullptr)
                {
                    ChipLogError(Zcl, "Could not find ChipStructs$AccessControlClusterTarget constructor");
                    return;
                }

                newElement_3 = env->NewObject(targetStructClass_4, targetStructCtor_4, newElement_3_cluster, newElement_3_endpoint,
                                              newElement_3_deviceType);
                chip::JniReferences::GetInstance().AddToList(newElement_0_targets, newElement_3);
            }
        }
        jobject newElement_0_fabricIndex;
        std::string newElement_0_fabricIndexClassName     = "java/lang/Integer";
        std::string newElement_0_fabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_fabricIndexClassName.c_str(),
                                                                      newElement_0_fabricIndexCtorSignature.c_str(),
                                                                      entry_0.fabricIndex, newElement_0_fabricIndex);

        jclass accessControlEntryStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$AccessControlClusterAccessControlEntry", accessControlEntryStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$AccessControlClusterAccessControlEntry");
            return;
        }
        jmethodID accessControlEntryStructCtor_1 = env->GetMethodID(
            accessControlEntryStructClass_1, "<init>",
            "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/ArrayList;Ljava/util/ArrayList;Ljava/lang/Integer;)V");
        if (accessControlEntryStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$AccessControlClusterAccessControlEntry constructor");
            return;
        }

        newElement_0 = env->NewObject(accessControlEntryStructClass_1, accessControlEntryStructCtor_1, newElement_0_privilege,
                                      newElement_0_authMode, newElement_0_subjects, newElement_0_targets, newElement_0_fabricIndex);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAccessControlExtensionAttributeCallback::CHIPAccessControlExtensionAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAccessControlClusterExtensionAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAccessControlExtensionAttributeCallback::~CHIPAccessControlExtensionAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAccessControlExtensionAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::AccessControl::Structs::ExtensionEntry::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAccessControlExtensionAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAccessControlExtensionAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_data;
        jbyteArray newElement_0_dataByteArray = env->NewByteArray(static_cast<jsize>(entry_0.data.size()));
        env->SetByteArrayRegion(newElement_0_dataByteArray, 0, static_cast<jsize>(entry_0.data.size()),
                                reinterpret_cast<const jbyte *>(entry_0.data.data()));
        newElement_0_data = newElement_0_dataByteArray;
        jobject newElement_0_fabricIndex;
        std::string newElement_0_fabricIndexClassName     = "java/lang/Integer";
        std::string newElement_0_fabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_fabricIndexClassName.c_str(),
                                                                      newElement_0_fabricIndexCtorSignature.c_str(),
                                                                      entry_0.fabricIndex, newElement_0_fabricIndex);

        jclass extensionEntryStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$AccessControlClusterExtensionEntry", extensionEntryStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$AccessControlClusterExtensionEntry");
            return;
        }
        jmethodID extensionEntryStructCtor_1 = env->GetMethodID(extensionEntryStructClass_1, "<init>", "([BLjava/lang/Integer;)V");
        if (extensionEntryStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$AccessControlClusterExtensionEntry constructor");
            return;
        }

        newElement_0 =
            env->NewObject(extensionEntryStructClass_1, extensionEntryStructCtor_1, newElement_0_data, newElement_0_fabricIndex);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAccessControlGeneratedCommandListAttributeCallback::CHIPAccessControlGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPAccessControlClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAccessControlGeneratedCommandListAttributeCallback::~CHIPAccessControlGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAccessControlGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAccessControlGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAccessControlGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAccessControlAcceptedCommandListAttributeCallback::CHIPAccessControlAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPAccessControlClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAccessControlAcceptedCommandListAttributeCallback::~CHIPAccessControlAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAccessControlAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAccessControlAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAccessControlAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAccessControlAttributeListAttributeCallback::CHIPAccessControlAttributeListAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPAccessControlClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAccessControlAttributeListAttributeCallback::~CHIPAccessControlAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAccessControlAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAccessControlAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAccessControlAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBridgedActionsActionListAttributeCallback::CHIPBridgedActionsActionListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBridgedActionsClusterActionListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBridgedActionsActionListAttributeCallback::~CHIPBridgedActionsActionListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBridgedActionsActionListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::BridgedActions::Structs::ActionStruct::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBridgedActionsActionListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBridgedActionsActionListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_actionID;
        std::string newElement_0_actionIDClassName     = "java/lang/Integer";
        std::string newElement_0_actionIDCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_actionIDClassName.c_str(),
                                                                       newElement_0_actionIDCtorSignature.c_str(), entry_0.actionID,
                                                                       newElement_0_actionID);
        jobject newElement_0_name;
        newElement_0_name = env->NewStringUTF(std::string(entry_0.name.data(), entry_0.name.size()).c_str());
        jobject newElement_0_type;
        std::string newElement_0_typeClassName     = "java/lang/Integer";
        std::string newElement_0_typeCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_typeClassName.c_str(),
                                                                      newElement_0_typeCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(entry_0.type), newElement_0_type);
        jobject newElement_0_endpointListID;
        std::string newElement_0_endpointListIDClassName     = "java/lang/Integer";
        std::string newElement_0_endpointListIDCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_endpointListIDClassName.c_str(),
                                                                       newElement_0_endpointListIDCtorSignature.c_str(),
                                                                       entry_0.endpointListID, newElement_0_endpointListID);
        jobject newElement_0_supportedCommands;
        std::string newElement_0_supportedCommandsClassName     = "java/lang/Integer";
        std::string newElement_0_supportedCommandsCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_supportedCommandsClassName.c_str(),
                                                                       newElement_0_supportedCommandsCtorSignature.c_str(),
                                                                       entry_0.supportedCommands, newElement_0_supportedCommands);
        jobject newElement_0_status;
        std::string newElement_0_statusClassName     = "java/lang/Integer";
        std::string newElement_0_statusCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_statusClassName.c_str(),
                                                                      newElement_0_statusCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(entry_0.status), newElement_0_status);

        jclass actionStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$BridgedActionsClusterActionStruct", actionStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$BridgedActionsClusterActionStruct");
            return;
        }
        jmethodID actionStructStructCtor_1 = env->GetMethodID(
            actionStructStructClass_1, "<init>",
            "(Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V");
        if (actionStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$BridgedActionsClusterActionStruct constructor");
            return;
        }

        newElement_0 =
            env->NewObject(actionStructStructClass_1, actionStructStructCtor_1, newElement_0_actionID, newElement_0_name,
                           newElement_0_type, newElement_0_endpointListID, newElement_0_supportedCommands, newElement_0_status);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBridgedActionsEndpointListAttributeCallback::CHIPBridgedActionsEndpointListAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPBridgedActionsClusterEndpointListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBridgedActionsEndpointListAttributeCallback::~CHIPBridgedActionsEndpointListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBridgedActionsEndpointListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::BridgedActions::Structs::EndpointListStruct::DecodableType> &
        list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBridgedActionsEndpointListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBridgedActionsEndpointListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_endpointListID;
        std::string newElement_0_endpointListIDClassName     = "java/lang/Integer";
        std::string newElement_0_endpointListIDCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_endpointListIDClassName.c_str(),
                                                                       newElement_0_endpointListIDCtorSignature.c_str(),
                                                                       entry_0.endpointListID, newElement_0_endpointListID);
        jobject newElement_0_name;
        newElement_0_name = env->NewStringUTF(std::string(entry_0.name.data(), entry_0.name.size()).c_str());
        jobject newElement_0_type;
        std::string newElement_0_typeClassName     = "java/lang/Integer";
        std::string newElement_0_typeCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_typeClassName.c_str(),
                                                                      newElement_0_typeCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(entry_0.type), newElement_0_type);
        jobject newElement_0_endpoints;
        chip::JniReferences::GetInstance().CreateArrayList(newElement_0_endpoints);

        auto iter_newElement_0_endpoints_2 = entry_0.endpoints.begin();
        while (iter_newElement_0_endpoints_2.Next())
        {
            auto & entry_2 = iter_newElement_0_endpoints_2.GetValue();
            jobject newElement_2;
            std::string newElement_2ClassName     = "java/lang/Integer";
            std::string newElement_2CtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
                newElement_2ClassName.c_str(), newElement_2CtorSignature.c_str(), entry_2, newElement_2);
            chip::JniReferences::GetInstance().AddToList(newElement_0_endpoints, newElement_2);
        }

        jclass endpointListStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$BridgedActionsClusterEndpointListStruct", endpointListStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$BridgedActionsClusterEndpointListStruct");
            return;
        }
        jmethodID endpointListStructStructCtor_1 =
            env->GetMethodID(endpointListStructStructClass_1, "<init>",
                             "(Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/ArrayList;)V");
        if (endpointListStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$BridgedActionsClusterEndpointListStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(endpointListStructStructClass_1, endpointListStructStructCtor_1, newElement_0_endpointListID,
                                      newElement_0_name, newElement_0_type, newElement_0_endpoints);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBridgedActionsGeneratedCommandListAttributeCallback::CHIPBridgedActionsGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBridgedActionsClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBridgedActionsGeneratedCommandListAttributeCallback::~CHIPBridgedActionsGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBridgedActionsGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBridgedActionsGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBridgedActionsGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBridgedActionsAcceptedCommandListAttributeCallback::CHIPBridgedActionsAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPBridgedActionsClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBridgedActionsAcceptedCommandListAttributeCallback::~CHIPBridgedActionsAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBridgedActionsAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBridgedActionsAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBridgedActionsAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBridgedActionsAttributeListAttributeCallback::CHIPBridgedActionsAttributeListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPBridgedActionsClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBridgedActionsAttributeListAttributeCallback::~CHIPBridgedActionsAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBridgedActionsAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBridgedActionsAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBridgedActionsAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBasicVendorIDAttributeCallback::CHIPBasicVendorIDAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBasicClusterVendorIDAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBasicVendorIDAttributeCallback::~CHIPBasicVendorIDAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBasicVendorIDAttributeCallback::CallbackFn(void * context, chip::VendorId value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPBasicVendorIDAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBasicVendorIDAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    std::string javaValueClassName     = "java/lang/Integer";
    std::string javaValueCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                   static_cast<uint16_t>(value), javaValue);

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPBasicGeneratedCommandListAttributeCallback::CHIPBasicGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPBasicClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBasicGeneratedCommandListAttributeCallback::~CHIPBasicGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBasicGeneratedCommandListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBasicGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBasicGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBasicAcceptedCommandListAttributeCallback::CHIPBasicAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBasicClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBasicAcceptedCommandListAttributeCallback::~CHIPBasicAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBasicAcceptedCommandListAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBasicAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBasicAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBasicAttributeListAttributeCallback::CHIPBasicAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBasicClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBasicAttributeListAttributeCallback::~CHIPBasicAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBasicAttributeListAttributeCallback::CallbackFn(void * context,
                                                         const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBasicAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBasicAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback::CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOtaSoftwareUpdateProviderClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback::~CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOtaSoftwareUpdateProviderAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback::
    CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOtaSoftwareUpdateRequestorClusterDefaultOtaProvidersAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback::
    ~CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<
        chip::app::Clusters::OtaSoftwareUpdateRequestor::Structs::ProviderLocation::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOtaSoftwareUpdateRequestorDefaultOtaProvidersAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_providerNodeID;
        std::string newElement_0_providerNodeIDClassName     = "java/lang/Long";
        std::string newElement_0_providerNodeIDCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_0_providerNodeIDClassName.c_str(),
                                                                       newElement_0_providerNodeIDCtorSignature.c_str(),
                                                                       entry_0.providerNodeID, newElement_0_providerNodeID);
        jobject newElement_0_endpoint;
        std::string newElement_0_endpointClassName     = "java/lang/Integer";
        std::string newElement_0_endpointCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_endpointClassName.c_str(),
                                                                       newElement_0_endpointCtorSignature.c_str(), entry_0.endpoint,
                                                                       newElement_0_endpoint);
        jobject newElement_0_fabricIndex;
        std::string newElement_0_fabricIndexClassName     = "java/lang/Integer";
        std::string newElement_0_fabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_fabricIndexClassName.c_str(),
                                                                      newElement_0_fabricIndexCtorSignature.c_str(),
                                                                      entry_0.fabricIndex, newElement_0_fabricIndex);

        jclass providerLocationStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$OtaSoftwareUpdateRequestorClusterProviderLocation",
            providerLocationStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$OtaSoftwareUpdateRequestorClusterProviderLocation");
            return;
        }
        jmethodID providerLocationStructCtor_1 =
            env->GetMethodID(providerLocationStructClass_1, "<init>", "(Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;)V");
        if (providerLocationStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$OtaSoftwareUpdateRequestorClusterProviderLocation constructor");
            return;
        }

        newElement_0 = env->NewObject(providerLocationStructClass_1, providerLocationStructCtor_1, newElement_0_providerNodeID,
                                      newElement_0_endpoint, newElement_0_fabricIndex);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback::
    CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOtaSoftwareUpdateRequestorClusterUpdateStateProgressAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback::
    ~CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOtaSoftwareUpdateRequestorUpdateStateProgressAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback::CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOtaSoftwareUpdateRequestorClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback::~CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOtaSoftwareUpdateRequestorAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLocalizationConfigurationSupportedLocalesAttributeCallback::CHIPLocalizationConfigurationSupportedLocalesAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLocalizationConfigurationClusterSupportedLocalesAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLocalizationConfigurationSupportedLocalesAttributeCallback::~CHIPLocalizationConfigurationSupportedLocalesAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLocalizationConfigurationSupportedLocalesAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CharSpan> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPLocalizationConfigurationSupportedLocalesAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLocalizationConfigurationSupportedLocalesAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        newElement_0 = env->NewStringUTF(std::string(entry_0.data(), entry_0.size()).c_str());
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback::
    CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLocalizationConfigurationClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback::
    ~CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLocalizationConfigurationGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback::
    CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLocalizationConfigurationClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback::
    ~CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLocalizationConfigurationAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback::
    CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTimeFormatLocalizationClusterSupportedCalendarTypesAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback::
    ~CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::app::Clusters::TimeFormatLocalization::CalendarType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTimeFormatLocalizationSupportedCalendarTypesAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), static_cast<uint8_t>(entry_0), newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback::CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTimeFormatLocalizationClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback::~CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTimeFormatLocalizationGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback::CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTimeFormatLocalizationClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback::~CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTimeFormatLocalizationAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPUnitLocalizationAttributeListAttributeCallback::CHIPUnitLocalizationAttributeListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPUnitLocalizationClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitLocalizationAttributeListAttributeCallback::~CHIPUnitLocalizationAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitLocalizationAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPUnitLocalizationAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitLocalizationAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPowerSourceConfigurationSourcesAttributeCallback::CHIPPowerSourceConfigurationSourcesAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceConfigurationClusterSourcesAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceConfigurationSourcesAttributeCallback::~CHIPPowerSourceConfigurationSourcesAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceConfigurationSourcesAttributeCallback::CallbackFn(void * context,
                                                                      const chip::app::DataModel::DecodableList<uint8_t> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPowerSourceConfigurationSourcesAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceConfigurationSourcesAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0ClassName.c_str(),
                                                                      newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback::
    CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceConfigurationClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback::
    ~CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceConfigurationGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback::CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceConfigurationClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback::
    ~CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceConfigurationAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPowerSourceConfigurationAttributeListAttributeCallback::CHIPPowerSourceConfigurationAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceConfigurationClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceConfigurationAttributeListAttributeCallback::~CHIPPowerSourceConfigurationAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceConfigurationAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPowerSourceConfigurationAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceConfigurationAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback::CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterWiredAssessedInputVoltageAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback::~CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback::CallbackFn(void * context,
                                                                           const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceWiredAssessedInputVoltageAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback::CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterWiredAssessedInputFrequencyAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback::~CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback::CallbackFn(void * context,
                                                                             const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceWiredAssessedInputFrequencyAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPowerSourceWiredAssessedCurrentAttributeCallback::CHIPPowerSourceWiredAssessedCurrentAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterWiredAssessedCurrentAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceWiredAssessedCurrentAttributeCallback::~CHIPPowerSourceWiredAssessedCurrentAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceWiredAssessedCurrentAttributeCallback::CallbackFn(void * context,
                                                                      const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPowerSourceWiredAssessedCurrentAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceWiredAssessedCurrentAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPowerSourceActiveWiredFaultsAttributeCallback::CHIPPowerSourceActiveWiredFaultsAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterActiveWiredFaultsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceActiveWiredFaultsAttributeCallback::~CHIPPowerSourceActiveWiredFaultsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceActiveWiredFaultsAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::app::Clusters::PowerSource::WiredFault> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPowerSourceActiveWiredFaultsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceActiveWiredFaultsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), static_cast<uint8_t>(entry_0), newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPowerSourceBatVoltageAttributeCallback::CHIPPowerSourceBatVoltageAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterBatVoltageAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceBatVoltageAttributeCallback::~CHIPPowerSourceBatVoltageAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceBatVoltageAttributeCallback::CallbackFn(void * context, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPowerSourceBatVoltageAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceBatVoltageAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPowerSourceBatPercentRemainingAttributeCallback::CHIPPowerSourceBatPercentRemainingAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterBatPercentRemainingAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceBatPercentRemainingAttributeCallback::~CHIPPowerSourceBatPercentRemainingAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceBatPercentRemainingAttributeCallback::CallbackFn(void * context,
                                                                     const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPowerSourceBatPercentRemainingAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceBatPercentRemainingAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPowerSourceBatTimeRemainingAttributeCallback::CHIPPowerSourceBatTimeRemainingAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterBatTimeRemainingAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceBatTimeRemainingAttributeCallback::~CHIPPowerSourceBatTimeRemainingAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceBatTimeRemainingAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPowerSourceBatTimeRemainingAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceBatTimeRemainingAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPowerSourceActiveBatFaultsAttributeCallback::CHIPPowerSourceActiveBatFaultsAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterActiveBatFaultsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceActiveBatFaultsAttributeCallback::~CHIPPowerSourceActiveBatFaultsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceActiveBatFaultsAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::app::Clusters::PowerSource::BatFault> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPowerSourceActiveBatFaultsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceActiveBatFaultsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), static_cast<uint8_t>(entry_0), newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPowerSourceBatTimeToFullChargeAttributeCallback::CHIPPowerSourceBatTimeToFullChargeAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterBatTimeToFullChargeAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceBatTimeToFullChargeAttributeCallback::~CHIPPowerSourceBatTimeToFullChargeAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceBatTimeToFullChargeAttributeCallback::CallbackFn(void * context,
                                                                     const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPowerSourceBatTimeToFullChargeAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceBatTimeToFullChargeAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPowerSourceBatChargingCurrentAttributeCallback::CHIPPowerSourceBatChargingCurrentAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterBatChargingCurrentAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceBatChargingCurrentAttributeCallback::~CHIPPowerSourceBatChargingCurrentAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceBatChargingCurrentAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPowerSourceBatChargingCurrentAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceBatChargingCurrentAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPowerSourceActiveBatChargeFaultsAttributeCallback::CHIPPowerSourceActiveBatChargeFaultsAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterActiveBatChargeFaultsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceActiveBatChargeFaultsAttributeCallback::~CHIPPowerSourceActiveBatChargeFaultsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceActiveBatChargeFaultsAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::app::Clusters::PowerSource::BatChargeFault> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPowerSourceActiveBatChargeFaultsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceActiveBatChargeFaultsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), static_cast<uint8_t>(entry_0), newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPowerSourceGeneratedCommandListAttributeCallback::CHIPPowerSourceGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceGeneratedCommandListAttributeCallback::~CHIPPowerSourceGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPowerSourceGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPowerSourceAcceptedCommandListAttributeCallback::CHIPPowerSourceAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceAcceptedCommandListAttributeCallback::~CHIPPowerSourceAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPowerSourceAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPowerSourceAttributeListAttributeCallback::CHIPPowerSourceAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPowerSourceClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPowerSourceAttributeListAttributeCallback::~CHIPPowerSourceAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPowerSourceAttributeListAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPowerSourceAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPowerSourceAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGeneralCommissioningGeneratedCommandListAttributeCallback::CHIPGeneralCommissioningGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPGeneralCommissioningClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGeneralCommissioningGeneratedCommandListAttributeCallback::~CHIPGeneralCommissioningGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGeneralCommissioningGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGeneralCommissioningGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGeneralCommissioningGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGeneralCommissioningAcceptedCommandListAttributeCallback::CHIPGeneralCommissioningAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPGeneralCommissioningClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGeneralCommissioningAcceptedCommandListAttributeCallback::~CHIPGeneralCommissioningAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGeneralCommissioningAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGeneralCommissioningAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGeneralCommissioningAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGeneralCommissioningAttributeListAttributeCallback::CHIPGeneralCommissioningAttributeListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPGeneralCommissioningClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGeneralCommissioningAttributeListAttributeCallback::~CHIPGeneralCommissioningAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGeneralCommissioningAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGeneralCommissioningAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGeneralCommissioningAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPNetworkCommissioningNetworksAttributeCallback::CHIPNetworkCommissioningNetworksAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPNetworkCommissioningClusterNetworksAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNetworkCommissioningNetworksAttributeCallback::~CHIPNetworkCommissioningNetworksAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNetworkCommissioningNetworksAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::NetworkCommissioning::Structs::NetworkInfo::DecodableType> &
        list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPNetworkCommissioningNetworksAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNetworkCommissioningNetworksAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_networkID;
        jbyteArray newElement_0_networkIDByteArray = env->NewByteArray(static_cast<jsize>(entry_0.networkID.size()));
        env->SetByteArrayRegion(newElement_0_networkIDByteArray, 0, static_cast<jsize>(entry_0.networkID.size()),
                                reinterpret_cast<const jbyte *>(entry_0.networkID.data()));
        newElement_0_networkID = newElement_0_networkIDByteArray;
        jobject newElement_0_connected;
        std::string newElement_0_connectedClassName     = "java/lang/Boolean";
        std::string newElement_0_connectedCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(newElement_0_connectedClassName.c_str(),
                                                                   newElement_0_connectedCtorSignature.c_str(), entry_0.connected,
                                                                   newElement_0_connected);

        jclass networkInfoStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$NetworkCommissioningClusterNetworkInfo", networkInfoStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$NetworkCommissioningClusterNetworkInfo");
            return;
        }
        jmethodID networkInfoStructCtor_1 = env->GetMethodID(networkInfoStructClass_1, "<init>", "([BLjava/lang/Boolean;)V");
        if (networkInfoStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$NetworkCommissioningClusterNetworkInfo constructor");
            return;
        }

        newElement_0 =
            env->NewObject(networkInfoStructClass_1, networkInfoStructCtor_1, newElement_0_networkID, newElement_0_connected);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback::CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNetworkCommissioningClusterLastNetworkingStatusAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback::~CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::Nullable<chip::app::Clusters::NetworkCommissioning::NetworkCommissioningStatus> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNetworkCommissioningLastNetworkingStatusAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(value.Value()), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPNetworkCommissioningLastNetworkIDAttributeCallback::CHIPNetworkCommissioningLastNetworkIDAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPNetworkCommissioningClusterLastNetworkIDAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNetworkCommissioningLastNetworkIDAttributeCallback::~CHIPNetworkCommissioningLastNetworkIDAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNetworkCommissioningLastNetworkIDAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::ByteSpan> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPNetworkCommissioningLastNetworkIDAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNetworkCommissioningLastNetworkIDAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "([B)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        jbyteArray javaValueByteArray = env->NewByteArray(static_cast<jsize>(value.Value().size()));
        env->SetByteArrayRegion(javaValueByteArray, 0, static_cast<jsize>(value.Value().size()),
                                reinterpret_cast<const jbyte *>(value.Value().data()));
        javaValue = javaValueByteArray;
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback::CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNetworkCommissioningClusterLastConnectErrorValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback::~CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<int32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNetworkCommissioningLastConnectErrorValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPNetworkCommissioningGeneratedCommandListAttributeCallback::CHIPNetworkCommissioningGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNetworkCommissioningClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNetworkCommissioningGeneratedCommandListAttributeCallback::~CHIPNetworkCommissioningGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNetworkCommissioningGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPNetworkCommissioningGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNetworkCommissioningGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPNetworkCommissioningAcceptedCommandListAttributeCallback::CHIPNetworkCommissioningAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNetworkCommissioningClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNetworkCommissioningAcceptedCommandListAttributeCallback::~CHIPNetworkCommissioningAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNetworkCommissioningAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPNetworkCommissioningAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNetworkCommissioningAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDiagnosticLogsGeneratedCommandListAttributeCallback::CHIPDiagnosticLogsGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDiagnosticLogsClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDiagnosticLogsGeneratedCommandListAttributeCallback::~CHIPDiagnosticLogsGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDiagnosticLogsGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDiagnosticLogsGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDiagnosticLogsGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDiagnosticLogsAcceptedCommandListAttributeCallback::CHIPDiagnosticLogsAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPDiagnosticLogsClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDiagnosticLogsAcceptedCommandListAttributeCallback::~CHIPDiagnosticLogsAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDiagnosticLogsAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDiagnosticLogsAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDiagnosticLogsAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDiagnosticLogsAttributeListAttributeCallback::CHIPDiagnosticLogsAttributeListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPDiagnosticLogsClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDiagnosticLogsAttributeListAttributeCallback::~CHIPDiagnosticLogsAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDiagnosticLogsAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDiagnosticLogsAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDiagnosticLogsAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback::CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPGeneralDiagnosticsClusterNetworkInterfacesAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback::~CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<
        chip::app::Clusters::GeneralDiagnostics::Structs::NetworkInterfaceType::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGeneralDiagnosticsNetworkInterfacesAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_name;
        newElement_0_name = env->NewStringUTF(std::string(entry_0.name.data(), entry_0.name.size()).c_str());
        jobject newElement_0_isOperational;
        std::string newElement_0_isOperationalClassName     = "java/lang/Boolean";
        std::string newElement_0_isOperationalCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(newElement_0_isOperationalClassName.c_str(),
                                                                   newElement_0_isOperationalCtorSignature.c_str(),
                                                                   entry_0.isOperational, newElement_0_isOperational);
        jobject newElement_0_offPremiseServicesReachableIPv4;
        if (entry_0.offPremiseServicesReachableIPv4.IsNull())
        {
            newElement_0_offPremiseServicesReachableIPv4 = nullptr;
        }
        else
        {
            std::string newElement_0_offPremiseServicesReachableIPv4ClassName     = "java/lang/Boolean";
            std::string newElement_0_offPremiseServicesReachableIPv4CtorSignature = "(Z)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
                newElement_0_offPremiseServicesReachableIPv4ClassName.c_str(),
                newElement_0_offPremiseServicesReachableIPv4CtorSignature.c_str(), entry_0.offPremiseServicesReachableIPv4.Value(),
                newElement_0_offPremiseServicesReachableIPv4);
        }
        jobject newElement_0_offPremiseServicesReachableIPv6;
        if (entry_0.offPremiseServicesReachableIPv6.IsNull())
        {
            newElement_0_offPremiseServicesReachableIPv6 = nullptr;
        }
        else
        {
            std::string newElement_0_offPremiseServicesReachableIPv6ClassName     = "java/lang/Boolean";
            std::string newElement_0_offPremiseServicesReachableIPv6CtorSignature = "(Z)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
                newElement_0_offPremiseServicesReachableIPv6ClassName.c_str(),
                newElement_0_offPremiseServicesReachableIPv6CtorSignature.c_str(), entry_0.offPremiseServicesReachableIPv6.Value(),
                newElement_0_offPremiseServicesReachableIPv6);
        }
        jobject newElement_0_hardwareAddress;
        jbyteArray newElement_0_hardwareAddressByteArray = env->NewByteArray(static_cast<jsize>(entry_0.hardwareAddress.size()));
        env->SetByteArrayRegion(newElement_0_hardwareAddressByteArray, 0, static_cast<jsize>(entry_0.hardwareAddress.size()),
                                reinterpret_cast<const jbyte *>(entry_0.hardwareAddress.data()));
        newElement_0_hardwareAddress = newElement_0_hardwareAddressByteArray;
        jobject newElement_0_IPv4Addresses;
        chip::JniReferences::GetInstance().CreateArrayList(newElement_0_IPv4Addresses);

        auto iter_newElement_0_IPv4Addresses_2 = entry_0.IPv4Addresses.begin();
        while (iter_newElement_0_IPv4Addresses_2.Next())
        {
            auto & entry_2 = iter_newElement_0_IPv4Addresses_2.GetValue();
            jobject newElement_2;
            jbyteArray newElement_2ByteArray = env->NewByteArray(static_cast<jsize>(entry_2.size()));
            env->SetByteArrayRegion(newElement_2ByteArray, 0, static_cast<jsize>(entry_2.size()),
                                    reinterpret_cast<const jbyte *>(entry_2.data()));
            newElement_2 = newElement_2ByteArray;
            chip::JniReferences::GetInstance().AddToList(newElement_0_IPv4Addresses, newElement_2);
        }
        jobject newElement_0_IPv6Addresses;
        chip::JniReferences::GetInstance().CreateArrayList(newElement_0_IPv6Addresses);

        auto iter_newElement_0_IPv6Addresses_2 = entry_0.IPv6Addresses.begin();
        while (iter_newElement_0_IPv6Addresses_2.Next())
        {
            auto & entry_2 = iter_newElement_0_IPv6Addresses_2.GetValue();
            jobject newElement_2;
            jbyteArray newElement_2ByteArray = env->NewByteArray(static_cast<jsize>(entry_2.size()));
            env->SetByteArrayRegion(newElement_2ByteArray, 0, static_cast<jsize>(entry_2.size()),
                                    reinterpret_cast<const jbyte *>(entry_2.data()));
            newElement_2 = newElement_2ByteArray;
            chip::JniReferences::GetInstance().AddToList(newElement_0_IPv6Addresses, newElement_2);
        }
        jobject newElement_0_type;
        std::string newElement_0_typeClassName     = "java/lang/Integer";
        std::string newElement_0_typeCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_typeClassName.c_str(),
                                                                      newElement_0_typeCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(entry_0.type), newElement_0_type);

        jclass networkInterfaceTypeStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$GeneralDiagnosticsClusterNetworkInterfaceType",
            networkInterfaceTypeStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$GeneralDiagnosticsClusterNetworkInterfaceType");
            return;
        }
        jmethodID networkInterfaceTypeStructCtor_1 =
            env->GetMethodID(networkInterfaceTypeStructClass_1, "<init>",
                             "(Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;[BLjava/util/"
                             "ArrayList;Ljava/util/ArrayList;Ljava/lang/Integer;)V");
        if (networkInterfaceTypeStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$GeneralDiagnosticsClusterNetworkInterfaceType constructor");
            return;
        }

        newElement_0 = env->NewObject(networkInterfaceTypeStructClass_1, networkInterfaceTypeStructCtor_1, newElement_0_name,
                                      newElement_0_isOperational, newElement_0_offPremiseServicesReachableIPv4,
                                      newElement_0_offPremiseServicesReachableIPv6, newElement_0_hardwareAddress,
                                      newElement_0_IPv4Addresses, newElement_0_IPv6Addresses, newElement_0_type);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback::CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPGeneralDiagnosticsClusterActiveHardwareFaultsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback::~CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<uint8_t> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGeneralDiagnosticsActiveHardwareFaultsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0ClassName.c_str(),
                                                                      newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback::CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPGeneralDiagnosticsClusterActiveRadioFaultsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback::~CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback::CallbackFn(void * context,
                                                                          const chip::app::DataModel::DecodableList<uint8_t> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGeneralDiagnosticsActiveRadioFaultsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0ClassName.c_str(),
                                                                      newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback::CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPGeneralDiagnosticsClusterActiveNetworkFaultsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback::~CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<uint8_t> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGeneralDiagnosticsActiveNetworkFaultsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0ClassName.c_str(),
                                                                      newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback::CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPGeneralDiagnosticsClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback::~CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGeneralDiagnosticsGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback::CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPGeneralDiagnosticsClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback::~CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGeneralDiagnosticsAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGeneralDiagnosticsAttributeListAttributeCallback::CHIPGeneralDiagnosticsAttributeListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPGeneralDiagnosticsClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGeneralDiagnosticsAttributeListAttributeCallback::~CHIPGeneralDiagnosticsAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGeneralDiagnosticsAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGeneralDiagnosticsAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGeneralDiagnosticsAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback::CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPSoftwareDiagnosticsClusterThreadMetricsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback::~CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::SoftwareDiagnostics::Structs::ThreadMetrics::DecodableType> &
        list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSoftwareDiagnosticsThreadMetricsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_id;
        std::string newElement_0_idClassName     = "java/lang/Long";
        std::string newElement_0_idCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(
            newElement_0_idClassName.c_str(), newElement_0_idCtorSignature.c_str(), entry_0.id, newElement_0_id);
        jobject newElement_0_name;
        if (!entry_0.name.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_name);
        }
        else
        {
            jobject newElement_0_nameInsideOptional;
            newElement_0_nameInsideOptional =
                env->NewStringUTF(std::string(entry_0.name.Value().data(), entry_0.name.Value().size()).c_str());
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_nameInsideOptional, newElement_0_name);
        }
        jobject newElement_0_stackFreeCurrent;
        if (!entry_0.stackFreeCurrent.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_stackFreeCurrent);
        }
        else
        {
            jobject newElement_0_stackFreeCurrentInsideOptional;
            std::string newElement_0_stackFreeCurrentInsideOptionalClassName     = "java/lang/Long";
            std::string newElement_0_stackFreeCurrentInsideOptionalCtorSignature = "(J)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
                newElement_0_stackFreeCurrentInsideOptionalClassName.c_str(),
                newElement_0_stackFreeCurrentInsideOptionalCtorSignature.c_str(), entry_0.stackFreeCurrent.Value(),
                newElement_0_stackFreeCurrentInsideOptional);
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_stackFreeCurrentInsideOptional,
                                                              newElement_0_stackFreeCurrent);
        }
        jobject newElement_0_stackFreeMinimum;
        if (!entry_0.stackFreeMinimum.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_stackFreeMinimum);
        }
        else
        {
            jobject newElement_0_stackFreeMinimumInsideOptional;
            std::string newElement_0_stackFreeMinimumInsideOptionalClassName     = "java/lang/Long";
            std::string newElement_0_stackFreeMinimumInsideOptionalCtorSignature = "(J)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
                newElement_0_stackFreeMinimumInsideOptionalClassName.c_str(),
                newElement_0_stackFreeMinimumInsideOptionalCtorSignature.c_str(), entry_0.stackFreeMinimum.Value(),
                newElement_0_stackFreeMinimumInsideOptional);
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_stackFreeMinimumInsideOptional,
                                                              newElement_0_stackFreeMinimum);
        }
        jobject newElement_0_stackSize;
        if (!entry_0.stackSize.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_stackSize);
        }
        else
        {
            jobject newElement_0_stackSizeInsideOptional;
            std::string newElement_0_stackSizeInsideOptionalClassName     = "java/lang/Long";
            std::string newElement_0_stackSizeInsideOptionalCtorSignature = "(J)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
                newElement_0_stackSizeInsideOptionalClassName.c_str(), newElement_0_stackSizeInsideOptionalCtorSignature.c_str(),
                entry_0.stackSize.Value(), newElement_0_stackSizeInsideOptional);
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_stackSizeInsideOptional, newElement_0_stackSize);
        }

        jclass threadMetricsStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$SoftwareDiagnosticsClusterThreadMetrics", threadMetricsStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$SoftwareDiagnosticsClusterThreadMetrics");
            return;
        }
        jmethodID threadMetricsStructCtor_1 =
            env->GetMethodID(threadMetricsStructClass_1, "<init>",
                             "(Ljava/lang/Long;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V");
        if (threadMetricsStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$SoftwareDiagnosticsClusterThreadMetrics constructor");
            return;
        }

        newElement_0 = env->NewObject(threadMetricsStructClass_1, threadMetricsStructCtor_1, newElement_0_id, newElement_0_name,
                                      newElement_0_stackFreeCurrent, newElement_0_stackFreeMinimum, newElement_0_stackSize);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback::CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSoftwareDiagnosticsClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback::~CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSoftwareDiagnosticsGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback::CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSoftwareDiagnosticsClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback::~CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSoftwareDiagnosticsAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSoftwareDiagnosticsAttributeListAttributeCallback::CHIPSoftwareDiagnosticsAttributeListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPSoftwareDiagnosticsClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSoftwareDiagnosticsAttributeListAttributeCallback::~CHIPSoftwareDiagnosticsAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSoftwareDiagnosticsAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPSoftwareDiagnosticsAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSoftwareDiagnosticsAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThreadNetworkDiagnosticsChannelAttributeCallback::CHIPThreadNetworkDiagnosticsChannelAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterChannelAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsChannelAttributeCallback::~CHIPThreadNetworkDiagnosticsChannelAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsChannelAttributeCallback::CallbackFn(void * context,
                                                                      const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsChannelAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsChannelAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback::CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback::~CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::app::Clusters::ThreadNetworkDiagnostics::RoutingRole> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsRoutingRoleAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(value.Value()), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback::CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterNetworkNameAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback::~CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::CharSpan> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsNetworkNameAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/String;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        javaValue = env->NewStringUTF(std::string(value.Value().data(), value.Value().size()).c_str());
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsPanIdAttributeCallback::CHIPThreadNetworkDiagnosticsPanIdAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterPanIdAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsPanIdAttributeCallback::~CHIPThreadNetworkDiagnosticsPanIdAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsPanIdAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsPanIdAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsPanIdAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback::CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterExtendedPanIdAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback::~CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback::CallbackFn(void * context,
                                                                            const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsExtendedPanIdAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback::CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterMeshLocalPrefixAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback::~CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::ByteSpan> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsMeshLocalPrefixAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "([B)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        jbyteArray javaValueByteArray = env->NewByteArray(static_cast<jsize>(value.Value().size()));
        env->SetByteArrayRegion(javaValueByteArray, 0, static_cast<jsize>(value.Value().size()),
                                reinterpret_cast<const jbyte *>(value.Value().data()));
        javaValue = javaValueByteArray;
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback::CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterNeighborTableListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback::~CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<
        chip::app::Clusters::ThreadNetworkDiagnostics::Structs::NeighborTable::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsNeighborTableListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_extAddress;
        std::string newElement_0_extAddressClassName     = "java/lang/Long";
        std::string newElement_0_extAddressCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_0_extAddressClassName.c_str(),
                                                                       newElement_0_extAddressCtorSignature.c_str(),
                                                                       entry_0.extAddress, newElement_0_extAddress);
        jobject newElement_0_age;
        std::string newElement_0_ageClassName     = "java/lang/Long";
        std::string newElement_0_ageCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
            newElement_0_ageClassName.c_str(), newElement_0_ageCtorSignature.c_str(), entry_0.age, newElement_0_age);
        jobject newElement_0_rloc16;
        std::string newElement_0_rloc16ClassName     = "java/lang/Integer";
        std::string newElement_0_rloc16CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            newElement_0_rloc16ClassName.c_str(), newElement_0_rloc16CtorSignature.c_str(), entry_0.rloc16, newElement_0_rloc16);
        jobject newElement_0_linkFrameCounter;
        std::string newElement_0_linkFrameCounterClassName     = "java/lang/Long";
        std::string newElement_0_linkFrameCounterCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0_linkFrameCounterClassName.c_str(),
                                                                       newElement_0_linkFrameCounterCtorSignature.c_str(),
                                                                       entry_0.linkFrameCounter, newElement_0_linkFrameCounter);
        jobject newElement_0_mleFrameCounter;
        std::string newElement_0_mleFrameCounterClassName     = "java/lang/Long";
        std::string newElement_0_mleFrameCounterCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0_mleFrameCounterClassName.c_str(),
                                                                       newElement_0_mleFrameCounterCtorSignature.c_str(),
                                                                       entry_0.mleFrameCounter, newElement_0_mleFrameCounter);
        jobject newElement_0_lqi;
        std::string newElement_0_lqiClassName     = "java/lang/Integer";
        std::string newElement_0_lqiCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_lqiClassName.c_str(), newElement_0_lqiCtorSignature.c_str(), entry_0.lqi, newElement_0_lqi);
        jobject newElement_0_averageRssi;
        if (entry_0.averageRssi.IsNull())
        {
            newElement_0_averageRssi = nullptr;
        }
        else
        {
            std::string newElement_0_averageRssiClassName     = "java/lang/Integer";
            std::string newElement_0_averageRssiCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<int8_t>(newElement_0_averageRssiClassName.c_str(),
                                                                         newElement_0_averageRssiCtorSignature.c_str(),
                                                                         entry_0.averageRssi.Value(), newElement_0_averageRssi);
        }
        jobject newElement_0_lastRssi;
        if (entry_0.lastRssi.IsNull())
        {
            newElement_0_lastRssi = nullptr;
        }
        else
        {
            std::string newElement_0_lastRssiClassName     = "java/lang/Integer";
            std::string newElement_0_lastRssiCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<int8_t>(newElement_0_lastRssiClassName.c_str(),
                                                                         newElement_0_lastRssiCtorSignature.c_str(),
                                                                         entry_0.lastRssi.Value(), newElement_0_lastRssi);
        }
        jobject newElement_0_frameErrorRate;
        std::string newElement_0_frameErrorRateClassName     = "java/lang/Integer";
        std::string newElement_0_frameErrorRateCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_frameErrorRateClassName.c_str(),
                                                                      newElement_0_frameErrorRateCtorSignature.c_str(),
                                                                      entry_0.frameErrorRate, newElement_0_frameErrorRate);
        jobject newElement_0_messageErrorRate;
        std::string newElement_0_messageErrorRateClassName     = "java/lang/Integer";
        std::string newElement_0_messageErrorRateCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_messageErrorRateClassName.c_str(),
                                                                      newElement_0_messageErrorRateCtorSignature.c_str(),
                                                                      entry_0.messageErrorRate, newElement_0_messageErrorRate);
        jobject newElement_0_rxOnWhenIdle;
        std::string newElement_0_rxOnWhenIdleClassName     = "java/lang/Boolean";
        std::string newElement_0_rxOnWhenIdleCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(newElement_0_rxOnWhenIdleClassName.c_str(),
                                                                   newElement_0_rxOnWhenIdleCtorSignature.c_str(),
                                                                   entry_0.rxOnWhenIdle, newElement_0_rxOnWhenIdle);
        jobject newElement_0_fullThreadDevice;
        std::string newElement_0_fullThreadDeviceClassName     = "java/lang/Boolean";
        std::string newElement_0_fullThreadDeviceCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(newElement_0_fullThreadDeviceClassName.c_str(),
                                                                   newElement_0_fullThreadDeviceCtorSignature.c_str(),
                                                                   entry_0.fullThreadDevice, newElement_0_fullThreadDevice);
        jobject newElement_0_fullNetworkData;
        std::string newElement_0_fullNetworkDataClassName     = "java/lang/Boolean";
        std::string newElement_0_fullNetworkDataCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(newElement_0_fullNetworkDataClassName.c_str(),
                                                                   newElement_0_fullNetworkDataCtorSignature.c_str(),
                                                                   entry_0.fullNetworkData, newElement_0_fullNetworkData);
        jobject newElement_0_isChild;
        std::string newElement_0_isChildClassName     = "java/lang/Boolean";
        std::string newElement_0_isChildCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(newElement_0_isChildClassName.c_str(),
                                                                   newElement_0_isChildCtorSignature.c_str(), entry_0.isChild,
                                                                   newElement_0_isChild);

        jclass neighborTableStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$ThreadNetworkDiagnosticsClusterNeighborTable", neighborTableStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$ThreadNetworkDiagnosticsClusterNeighborTable");
            return;
        }
        jmethodID neighborTableStructCtor_1 =
            env->GetMethodID(neighborTableStructClass_1, "<init>",
                             "(Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/"
                             "Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/"
                             "Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;)V");
        if (neighborTableStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$ThreadNetworkDiagnosticsClusterNeighborTable constructor");
            return;
        }

        newElement_0 = env->NewObject(
            neighborTableStructClass_1, neighborTableStructCtor_1, newElement_0_extAddress, newElement_0_age, newElement_0_rloc16,
            newElement_0_linkFrameCounter, newElement_0_mleFrameCounter, newElement_0_lqi, newElement_0_averageRssi,
            newElement_0_lastRssi, newElement_0_frameErrorRate, newElement_0_messageErrorRate, newElement_0_rxOnWhenIdle,
            newElement_0_fullThreadDevice, newElement_0_fullNetworkData, newElement_0_isChild);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback::CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterRouteTableListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback::~CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::ThreadNetworkDiagnostics::Structs::RouteTable::DecodableType> &
        list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsRouteTableListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_extAddress;
        std::string newElement_0_extAddressClassName     = "java/lang/Long";
        std::string newElement_0_extAddressCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_0_extAddressClassName.c_str(),
                                                                       newElement_0_extAddressCtorSignature.c_str(),
                                                                       entry_0.extAddress, newElement_0_extAddress);
        jobject newElement_0_rloc16;
        std::string newElement_0_rloc16ClassName     = "java/lang/Integer";
        std::string newElement_0_rloc16CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            newElement_0_rloc16ClassName.c_str(), newElement_0_rloc16CtorSignature.c_str(), entry_0.rloc16, newElement_0_rloc16);
        jobject newElement_0_routerId;
        std::string newElement_0_routerIdClassName     = "java/lang/Integer";
        std::string newElement_0_routerIdCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_routerIdClassName.c_str(),
                                                                      newElement_0_routerIdCtorSignature.c_str(), entry_0.routerId,
                                                                      newElement_0_routerId);
        jobject newElement_0_nextHop;
        std::string newElement_0_nextHopClassName     = "java/lang/Integer";
        std::string newElement_0_nextHopCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_nextHopClassName.c_str(),
                                                                      newElement_0_nextHopCtorSignature.c_str(), entry_0.nextHop,
                                                                      newElement_0_nextHop);
        jobject newElement_0_pathCost;
        std::string newElement_0_pathCostClassName     = "java/lang/Integer";
        std::string newElement_0_pathCostCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_pathCostClassName.c_str(),
                                                                      newElement_0_pathCostCtorSignature.c_str(), entry_0.pathCost,
                                                                      newElement_0_pathCost);
        jobject newElement_0_LQIIn;
        std::string newElement_0_LQIInClassName     = "java/lang/Integer";
        std::string newElement_0_LQIInCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_LQIInClassName.c_str(), newElement_0_LQIInCtorSignature.c_str(), entry_0.LQIIn, newElement_0_LQIIn);
        jobject newElement_0_LQIOut;
        std::string newElement_0_LQIOutClassName     = "java/lang/Integer";
        std::string newElement_0_LQIOutCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_LQIOutClassName.c_str(), newElement_0_LQIOutCtorSignature.c_str(), entry_0.LQIOut, newElement_0_LQIOut);
        jobject newElement_0_age;
        std::string newElement_0_ageClassName     = "java/lang/Integer";
        std::string newElement_0_ageCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_ageClassName.c_str(), newElement_0_ageCtorSignature.c_str(), entry_0.age, newElement_0_age);
        jobject newElement_0_allocated;
        std::string newElement_0_allocatedClassName     = "java/lang/Boolean";
        std::string newElement_0_allocatedCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(newElement_0_allocatedClassName.c_str(),
                                                                   newElement_0_allocatedCtorSignature.c_str(), entry_0.allocated,
                                                                   newElement_0_allocated);
        jobject newElement_0_linkEstablished;
        std::string newElement_0_linkEstablishedClassName     = "java/lang/Boolean";
        std::string newElement_0_linkEstablishedCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(newElement_0_linkEstablishedClassName.c_str(),
                                                                   newElement_0_linkEstablishedCtorSignature.c_str(),
                                                                   entry_0.linkEstablished, newElement_0_linkEstablished);

        jclass routeTableStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$ThreadNetworkDiagnosticsClusterRouteTable", routeTableStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$ThreadNetworkDiagnosticsClusterRouteTable");
            return;
        }
        jmethodID routeTableStructCtor_1 =
            env->GetMethodID(routeTableStructClass_1, "<init>",
                             "(Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/"
                             "lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Boolean;)V");
        if (routeTableStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$ThreadNetworkDiagnosticsClusterRouteTable constructor");
            return;
        }

        newElement_0 = env->NewObject(routeTableStructClass_1, routeTableStructCtor_1, newElement_0_extAddress, newElement_0_rloc16,
                                      newElement_0_routerId, newElement_0_nextHop, newElement_0_pathCost, newElement_0_LQIIn,
                                      newElement_0_LQIOut, newElement_0_age, newElement_0_allocated, newElement_0_linkEstablished);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback::CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterPartitionIdAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback::~CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback::CallbackFn(void * context,
                                                                          const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsPartitionIdAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsWeightingAttributeCallback::CHIPThreadNetworkDiagnosticsWeightingAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterWeightingAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsWeightingAttributeCallback::~CHIPThreadNetworkDiagnosticsWeightingAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsWeightingAttributeCallback::CallbackFn(void * context,
                                                                        const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsWeightingAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsWeightingAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback::CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterDataVersionAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback::~CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback::CallbackFn(void * context,
                                                                          const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsDataVersionAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback::CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterStableDataVersionAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback::~CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsStableDataVersionAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback::CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterLeaderRouterIdAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback::~CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback::CallbackFn(void * context,
                                                                             const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsLeaderRouterIdAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback::CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterActiveTimestampAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback::~CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsActiveTimestampAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback::CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterPendingTimestampAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback::~CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsPendingTimestampAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsDelayAttributeCallback::CHIPThreadNetworkDiagnosticsDelayAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterDelayAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsDelayAttributeCallback::~CHIPThreadNetworkDiagnosticsDelayAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsDelayAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsDelayAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsDelayAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsChannelMaskAttributeCallback::CHIPThreadNetworkDiagnosticsChannelMaskAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterChannelMaskAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsChannelMaskAttributeCallback::~CHIPThreadNetworkDiagnosticsChannelMaskAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsChannelMaskAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::ByteSpan> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThreadNetworkDiagnosticsChannelMaskAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsChannelMaskAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "([B)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        jbyteArray javaValueByteArray = env->NewByteArray(static_cast<jsize>(value.Value().size()));
        env->SetByteArrayRegion(javaValueByteArray, 0, static_cast<jsize>(value.Value().size()),
                                reinterpret_cast<const jbyte *>(value.Value().data()));
        javaValue = javaValueByteArray;
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback::
    CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterActiveNetworkFaultsListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback::
    ~CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::app::Clusters::ThreadNetworkDiagnostics::NetworkFault> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsActiveNetworkFaultsListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), static_cast<uint8_t>(entry_0), newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback::
    CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback::
    ~CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback::CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback::
    ~CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback::CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThreadNetworkDiagnosticsClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback::~CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWiFiNetworkDiagnosticsBssidAttributeCallback::CHIPWiFiNetworkDiagnosticsBssidAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterBssidAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsBssidAttributeCallback::~CHIPWiFiNetworkDiagnosticsBssidAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsBssidAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::Nullable<chip::ByteSpan> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsBssidAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsBssidAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "([B)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        jbyteArray javaValueByteArray = env->NewByteArray(static_cast<jsize>(value.Value().size()));
        env->SetByteArrayRegion(javaValueByteArray, 0, static_cast<jsize>(value.Value().size()),
                                reinterpret_cast<const jbyte *>(value.Value().data()));
        javaValue = javaValueByteArray;
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback::CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterSecurityTypeAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback::~CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::app::Clusters::WiFiNetworkDiagnostics::SecurityType> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsSecurityTypeAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(value.Value()), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback::CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterWiFiVersionAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback::~CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::app::Clusters::WiFiNetworkDiagnostics::WiFiVersionType> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsWiFiVersionAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(value.Value()), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback::CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterChannelNumberAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback::~CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback::CallbackFn(void * context,
                                                                          const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsChannelNumberAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsRssiAttributeCallback::CHIPWiFiNetworkDiagnosticsRssiAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterRssiAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsRssiAttributeCallback::~CHIPWiFiNetworkDiagnosticsRssiAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsRssiAttributeCallback::CallbackFn(void * context,
                                                                 const chip::app::DataModel::Nullable<int8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsRssiAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsRssiAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                     value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback::CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterBeaconLostCountAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback::~CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback::CallbackFn(void * context,
                                                                            const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsBeaconLostCountAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback::CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterBeaconRxCountAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback::~CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback::CallbackFn(void * context,
                                                                          const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsBeaconRxCountAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback::
    CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterPacketMulticastRxCountAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback::
    ~CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsPacketMulticastRxCountAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback::
    CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterPacketMulticastTxCountAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback::
    ~CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsPacketMulticastTxCountAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback::CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterPacketUnicastRxCountAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback::~CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsPacketUnicastRxCountAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback::CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterPacketUnicastTxCountAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback::~CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsPacketUnicastTxCountAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback::CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterCurrentMaxRateAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback::~CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback::CallbackFn(void * context,
                                                                           const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsCurrentMaxRateAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback::CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterOverrunCountAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback::~CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback::CallbackFn(void * context,
                                                                         const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsOverrunCountAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback::CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback::~CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback::CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback::~CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback::CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWiFiNetworkDiagnosticsClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback::~CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWiFiNetworkDiagnosticsAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback::CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterPHYRateAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback::~CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::app::Clusters::EthernetNetworkDiagnostics::PHYRateType> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthernetNetworkDiagnosticsPHYRateAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(value.Value()), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback::CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterFullDuplexAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback::~CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback::CallbackFn(void * context,
                                                                           const chip::app::DataModel::Nullable<bool> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthernetNetworkDiagnosticsFullDuplexAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Boolean;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Boolean";
        std::string javaValueCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                   value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback::CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterCarrierDetectAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback::~CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback::CallbackFn(void * context,
                                                                              const chip::app::DataModel::Nullable<bool> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthernetNetworkDiagnosticsCarrierDetectAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Boolean;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Boolean";
        std::string javaValueCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                   value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback::
    CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback::
    ~CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthernetNetworkDiagnosticsGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback::
    CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback::
    ~CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthernetNetworkDiagnosticsAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback::CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthernetNetworkDiagnosticsClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback::~CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthernetNetworkDiagnosticsAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBridgedDeviceBasicVendorIDAttributeCallback::CHIPBridgedDeviceBasicVendorIDAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPBridgedDeviceBasicClusterVendorIDAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBridgedDeviceBasicVendorIDAttributeCallback::~CHIPBridgedDeviceBasicVendorIDAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBridgedDeviceBasicVendorIDAttributeCallback::CallbackFn(void * context, chip::VendorId value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPBridgedDeviceBasicVendorIDAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBridgedDeviceBasicVendorIDAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    std::string javaValueClassName     = "java/lang/Integer";
    std::string javaValueCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                   static_cast<uint16_t>(value), javaValue);

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback::CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBridgedDeviceBasicClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback::~CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBridgedDeviceBasicGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback::CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBridgedDeviceBasicClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback::~CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBridgedDeviceBasicAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBridgedDeviceBasicAttributeListAttributeCallback::CHIPBridgedDeviceBasicAttributeListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPBridgedDeviceBasicClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBridgedDeviceBasicAttributeListAttributeCallback::~CHIPBridgedDeviceBasicAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBridgedDeviceBasicAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBridgedDeviceBasicAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBridgedDeviceBasicAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSwitchGeneratedCommandListAttributeCallback::CHIPSwitchGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPSwitchClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSwitchGeneratedCommandListAttributeCallback::~CHIPSwitchGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSwitchGeneratedCommandListAttributeCallback::CallbackFn(void * context,
                                                                 const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPSwitchGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSwitchGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSwitchAcceptedCommandListAttributeCallback::CHIPSwitchAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPSwitchClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSwitchAcceptedCommandListAttributeCallback::~CHIPSwitchAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSwitchAcceptedCommandListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPSwitchAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSwitchAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSwitchAttributeListAttributeCallback::CHIPSwitchAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSwitchClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSwitchAttributeListAttributeCallback::~CHIPSwitchAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSwitchAttributeListAttributeCallback::CallbackFn(void * context,
                                                          const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPSwitchAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSwitchAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback::CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAdministratorCommissioningClusterAdminFabricIndexAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback::~CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::FabricIndex> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAdministratorCommissioningAdminFabricIndexAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPAdministratorCommissioningAdminVendorIdAttributeCallback::CHIPAdministratorCommissioningAdminVendorIdAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAdministratorCommissioningClusterAdminVendorIdAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAdministratorCommissioningAdminVendorIdAttributeCallback::~CHIPAdministratorCommissioningAdminVendorIdAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAdministratorCommissioningAdminVendorIdAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPAdministratorCommissioningAdminVendorIdAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAdministratorCommissioningAdminVendorIdAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback::
    CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAdministratorCommissioningClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback::
    ~CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAdministratorCommissioningGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback::
    CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAdministratorCommissioningClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback::
    ~CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAdministratorCommissioningAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAdministratorCommissioningAttributeListAttributeCallback::CHIPAdministratorCommissioningAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAdministratorCommissioningClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAdministratorCommissioningAttributeListAttributeCallback::~CHIPAdministratorCommissioningAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAdministratorCommissioningAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAdministratorCommissioningAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAdministratorCommissioningAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalCredentialsNOCsAttributeCallback::CHIPOperationalCredentialsNOCsAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalCredentialsClusterNOCsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalCredentialsNOCsAttributeCallback::~CHIPOperationalCredentialsNOCsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalCredentialsNOCsAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::OperationalCredentials::Structs::NOCStruct::DecodableType> &
        list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOperationalCredentialsNOCsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalCredentialsNOCsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_noc;
        jbyteArray newElement_0_nocByteArray = env->NewByteArray(static_cast<jsize>(entry_0.noc.size()));
        env->SetByteArrayRegion(newElement_0_nocByteArray, 0, static_cast<jsize>(entry_0.noc.size()),
                                reinterpret_cast<const jbyte *>(entry_0.noc.data()));
        newElement_0_noc = newElement_0_nocByteArray;
        jobject newElement_0_icac;
        if (entry_0.icac.IsNull())
        {
            newElement_0_icac = nullptr;
        }
        else
        {
            jbyteArray newElement_0_icacByteArray = env->NewByteArray(static_cast<jsize>(entry_0.icac.Value().size()));
            env->SetByteArrayRegion(newElement_0_icacByteArray, 0, static_cast<jsize>(entry_0.icac.Value().size()),
                                    reinterpret_cast<const jbyte *>(entry_0.icac.Value().data()));
            newElement_0_icac = newElement_0_icacByteArray;
        }
        jobject newElement_0_fabricIndex;
        std::string newElement_0_fabricIndexClassName     = "java/lang/Integer";
        std::string newElement_0_fabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_fabricIndexClassName.c_str(),
                                                                      newElement_0_fabricIndexCtorSignature.c_str(),
                                                                      entry_0.fabricIndex, newElement_0_fabricIndex);

        jclass NOCStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$OperationalCredentialsClusterNOCStruct", NOCStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$OperationalCredentialsClusterNOCStruct");
            return;
        }
        jmethodID NOCStructStructCtor_1 = env->GetMethodID(NOCStructStructClass_1, "<init>", "([B[BLjava/lang/Integer;)V");
        if (NOCStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$OperationalCredentialsClusterNOCStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(NOCStructStructClass_1, NOCStructStructCtor_1, newElement_0_noc, newElement_0_icac,
                                      newElement_0_fabricIndex);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalCredentialsFabricsAttributeCallback::CHIPOperationalCredentialsFabricsAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalCredentialsClusterFabricsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalCredentialsFabricsAttributeCallback::~CHIPOperationalCredentialsFabricsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalCredentialsFabricsAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<
        chip::app::Clusters::OperationalCredentials::Structs::FabricDescriptor::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOperationalCredentialsFabricsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalCredentialsFabricsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_rootPublicKey;
        jbyteArray newElement_0_rootPublicKeyByteArray = env->NewByteArray(static_cast<jsize>(entry_0.rootPublicKey.size()));
        env->SetByteArrayRegion(newElement_0_rootPublicKeyByteArray, 0, static_cast<jsize>(entry_0.rootPublicKey.size()),
                                reinterpret_cast<const jbyte *>(entry_0.rootPublicKey.data()));
        newElement_0_rootPublicKey = newElement_0_rootPublicKeyByteArray;
        jobject newElement_0_vendorId;
        std::string newElement_0_vendorIdClassName     = "java/lang/Integer";
        std::string newElement_0_vendorIdCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            newElement_0_vendorIdClassName.c_str(), newElement_0_vendorIdCtorSignature.c_str(),
            static_cast<uint16_t>(entry_0.vendorId), newElement_0_vendorId);
        jobject newElement_0_fabricId;
        std::string newElement_0_fabricIdClassName     = "java/lang/Long";
        std::string newElement_0_fabricIdCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_0_fabricIdClassName.c_str(),
                                                                       newElement_0_fabricIdCtorSignature.c_str(), entry_0.fabricId,
                                                                       newElement_0_fabricId);
        jobject newElement_0_nodeId;
        std::string newElement_0_nodeIdClassName     = "java/lang/Long";
        std::string newElement_0_nodeIdCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(
            newElement_0_nodeIdClassName.c_str(), newElement_0_nodeIdCtorSignature.c_str(), entry_0.nodeId, newElement_0_nodeId);
        jobject newElement_0_label;
        newElement_0_label = env->NewStringUTF(std::string(entry_0.label.data(), entry_0.label.size()).c_str());
        jobject newElement_0_fabricIndex;
        std::string newElement_0_fabricIndexClassName     = "java/lang/Integer";
        std::string newElement_0_fabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_fabricIndexClassName.c_str(),
                                                                      newElement_0_fabricIndexCtorSignature.c_str(),
                                                                      entry_0.fabricIndex, newElement_0_fabricIndex);

        jclass fabricDescriptorStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$OperationalCredentialsClusterFabricDescriptor", fabricDescriptorStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$OperationalCredentialsClusterFabricDescriptor");
            return;
        }
        jmethodID fabricDescriptorStructCtor_1 =
            env->GetMethodID(fabricDescriptorStructClass_1, "<init>",
                             "([BLjava/lang/Integer;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/String;Ljava/lang/Integer;)V");
        if (fabricDescriptorStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$OperationalCredentialsClusterFabricDescriptor constructor");
            return;
        }

        newElement_0 = env->NewObject(fabricDescriptorStructClass_1, fabricDescriptorStructCtor_1, newElement_0_rootPublicKey,
                                      newElement_0_vendorId, newElement_0_fabricId, newElement_0_nodeId, newElement_0_label,
                                      newElement_0_fabricIndex);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback::
    CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalCredentialsClusterTrustedRootCertificatesAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback::
    ~CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::ByteSpan> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jbyteArray newElement_0ByteArray = env->NewByteArray(static_cast<jsize>(entry_0.size()));
        env->SetByteArrayRegion(newElement_0ByteArray, 0, static_cast<jsize>(entry_0.size()),
                                reinterpret_cast<const jbyte *>(entry_0.data()));
        newElement_0 = newElement_0ByteArray;
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalCredentialsGeneratedCommandListAttributeCallback::CHIPOperationalCredentialsGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalCredentialsClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalCredentialsGeneratedCommandListAttributeCallback::~CHIPOperationalCredentialsGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalCredentialsGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOperationalCredentialsGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalCredentialsGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalCredentialsAcceptedCommandListAttributeCallback::CHIPOperationalCredentialsAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalCredentialsClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalCredentialsAcceptedCommandListAttributeCallback::~CHIPOperationalCredentialsAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalCredentialsAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOperationalCredentialsAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalCredentialsAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalCredentialsAttributeListAttributeCallback::CHIPOperationalCredentialsAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalCredentialsClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalCredentialsAttributeListAttributeCallback::~CHIPOperationalCredentialsAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalCredentialsAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOperationalCredentialsAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalCredentialsAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGroupKeyManagementGroupKeyMapAttributeCallback::CHIPGroupKeyManagementGroupKeyMapAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPGroupKeyManagementClusterGroupKeyMapAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGroupKeyManagementGroupKeyMapAttributeCallback::~CHIPGroupKeyManagementGroupKeyMapAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGroupKeyManagementGroupKeyMapAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::GroupKeyManagement::Structs::GroupKeyMapStruct::DecodableType> &
        list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGroupKeyManagementGroupKeyMapAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGroupKeyManagementGroupKeyMapAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_groupId;
        std::string newElement_0_groupIdClassName     = "java/lang/Integer";
        std::string newElement_0_groupIdCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_groupIdClassName.c_str(),
                                                                       newElement_0_groupIdCtorSignature.c_str(), entry_0.groupId,
                                                                       newElement_0_groupId);
        jobject newElement_0_groupKeySetID;
        std::string newElement_0_groupKeySetIDClassName     = "java/lang/Integer";
        std::string newElement_0_groupKeySetIDCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_groupKeySetIDClassName.c_str(),
                                                                       newElement_0_groupKeySetIDCtorSignature.c_str(),
                                                                       entry_0.groupKeySetID, newElement_0_groupKeySetID);
        jobject newElement_0_fabricIndex;
        std::string newElement_0_fabricIndexClassName     = "java/lang/Integer";
        std::string newElement_0_fabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_fabricIndexClassName.c_str(),
                                                                      newElement_0_fabricIndexCtorSignature.c_str(),
                                                                      entry_0.fabricIndex, newElement_0_fabricIndex);

        jclass groupKeyMapStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$GroupKeyManagementClusterGroupKeyMapStruct", groupKeyMapStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$GroupKeyManagementClusterGroupKeyMapStruct");
            return;
        }
        jmethodID groupKeyMapStructStructCtor_1 = env->GetMethodID(groupKeyMapStructStructClass_1, "<init>",
                                                                   "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V");
        if (groupKeyMapStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$GroupKeyManagementClusterGroupKeyMapStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(groupKeyMapStructStructClass_1, groupKeyMapStructStructCtor_1, newElement_0_groupId,
                                      newElement_0_groupKeySetID, newElement_0_fabricIndex);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGroupKeyManagementGroupTableAttributeCallback::CHIPGroupKeyManagementGroupTableAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPGroupKeyManagementClusterGroupTableAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGroupKeyManagementGroupTableAttributeCallback::~CHIPGroupKeyManagementGroupTableAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGroupKeyManagementGroupTableAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::GroupKeyManagement::Structs::GroupInfoMapStruct::DecodableType> &
        list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGroupKeyManagementGroupTableAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGroupKeyManagementGroupTableAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_groupId;
        std::string newElement_0_groupIdClassName     = "java/lang/Integer";
        std::string newElement_0_groupIdCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_groupIdClassName.c_str(),
                                                                       newElement_0_groupIdCtorSignature.c_str(), entry_0.groupId,
                                                                       newElement_0_groupId);
        jobject newElement_0_endpoints;
        chip::JniReferences::GetInstance().CreateArrayList(newElement_0_endpoints);

        auto iter_newElement_0_endpoints_2 = entry_0.endpoints.begin();
        while (iter_newElement_0_endpoints_2.Next())
        {
            auto & entry_2 = iter_newElement_0_endpoints_2.GetValue();
            jobject newElement_2;
            std::string newElement_2ClassName     = "java/lang/Integer";
            std::string newElement_2CtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
                newElement_2ClassName.c_str(), newElement_2CtorSignature.c_str(), entry_2, newElement_2);
            chip::JniReferences::GetInstance().AddToList(newElement_0_endpoints, newElement_2);
        }
        jobject newElement_0_groupName;
        if (!entry_0.groupName.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_groupName);
        }
        else
        {
            jobject newElement_0_groupNameInsideOptional;
            newElement_0_groupNameInsideOptional =
                env->NewStringUTF(std::string(entry_0.groupName.Value().data(), entry_0.groupName.Value().size()).c_str());
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_groupNameInsideOptional, newElement_0_groupName);
        }
        jobject newElement_0_fabricIndex;
        std::string newElement_0_fabricIndexClassName     = "java/lang/Integer";
        std::string newElement_0_fabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_fabricIndexClassName.c_str(),
                                                                      newElement_0_fabricIndexCtorSignature.c_str(),
                                                                      entry_0.fabricIndex, newElement_0_fabricIndex);

        jclass groupInfoMapStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$GroupKeyManagementClusterGroupInfoMapStruct", groupInfoMapStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$GroupKeyManagementClusterGroupInfoMapStruct");
            return;
        }
        jmethodID groupInfoMapStructStructCtor_1 =
            env->GetMethodID(groupInfoMapStructStructClass_1, "<init>",
                             "(Ljava/lang/Integer;Ljava/util/ArrayList;Ljava/util/Optional;Ljava/lang/Integer;)V");
        if (groupInfoMapStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$GroupKeyManagementClusterGroupInfoMapStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(groupInfoMapStructStructClass_1, groupInfoMapStructStructCtor_1, newElement_0_groupId,
                                      newElement_0_endpoints, newElement_0_groupName, newElement_0_fabricIndex);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGroupKeyManagementGeneratedCommandListAttributeCallback::CHIPGroupKeyManagementGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPGroupKeyManagementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGroupKeyManagementGeneratedCommandListAttributeCallback::~CHIPGroupKeyManagementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGroupKeyManagementGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGroupKeyManagementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGroupKeyManagementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGroupKeyManagementAcceptedCommandListAttributeCallback::CHIPGroupKeyManagementAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPGroupKeyManagementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGroupKeyManagementAcceptedCommandListAttributeCallback::~CHIPGroupKeyManagementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGroupKeyManagementAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGroupKeyManagementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGroupKeyManagementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPGroupKeyManagementAttributeListAttributeCallback::CHIPGroupKeyManagementAttributeListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPGroupKeyManagementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPGroupKeyManagementAttributeListAttributeCallback::~CHIPGroupKeyManagementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPGroupKeyManagementAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPGroupKeyManagementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPGroupKeyManagementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFixedLabelLabelListAttributeCallback::CHIPFixedLabelLabelListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFixedLabelClusterLabelListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFixedLabelLabelListAttributeCallback::~CHIPFixedLabelLabelListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFixedLabelLabelListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::FixedLabel::Structs::LabelStruct::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFixedLabelLabelListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFixedLabelLabelListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_label;
        newElement_0_label = env->NewStringUTF(std::string(entry_0.label.data(), entry_0.label.size()).c_str());
        jobject newElement_0_value;
        newElement_0_value = env->NewStringUTF(std::string(entry_0.value.data(), entry_0.value.size()).c_str());

        jclass labelStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs$FixedLabelClusterLabelStruct",
                                                             labelStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$FixedLabelClusterLabelStruct");
            return;
        }
        jmethodID labelStructStructCtor_1 =
            env->GetMethodID(labelStructStructClass_1, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
        if (labelStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$FixedLabelClusterLabelStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(labelStructStructClass_1, labelStructStructCtor_1, newElement_0_label, newElement_0_value);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFixedLabelGeneratedCommandListAttributeCallback::CHIPFixedLabelGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPFixedLabelClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFixedLabelGeneratedCommandListAttributeCallback::~CHIPFixedLabelGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFixedLabelGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFixedLabelGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFixedLabelGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFixedLabelAcceptedCommandListAttributeCallback::CHIPFixedLabelAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPFixedLabelClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFixedLabelAcceptedCommandListAttributeCallback::~CHIPFixedLabelAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFixedLabelAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFixedLabelAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFixedLabelAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFixedLabelAttributeListAttributeCallback::CHIPFixedLabelAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFixedLabelClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFixedLabelAttributeListAttributeCallback::~CHIPFixedLabelAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFixedLabelAttributeListAttributeCallback::CallbackFn(void * context,
                                                              const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFixedLabelAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFixedLabelAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPUserLabelLabelListAttributeCallback::CHIPUserLabelLabelListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUserLabelClusterLabelListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUserLabelLabelListAttributeCallback::~CHIPUserLabelLabelListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUserLabelLabelListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::UserLabel::Structs::LabelStruct::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPUserLabelLabelListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUserLabelLabelListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_label;
        newElement_0_label = env->NewStringUTF(std::string(entry_0.label.data(), entry_0.label.size()).c_str());
        jobject newElement_0_value;
        newElement_0_value = env->NewStringUTF(std::string(entry_0.value.data(), entry_0.value.size()).c_str());

        jclass labelStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs$UserLabelClusterLabelStruct",
                                                             labelStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$UserLabelClusterLabelStruct");
            return;
        }
        jmethodID labelStructStructCtor_1 =
            env->GetMethodID(labelStructStructClass_1, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
        if (labelStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$UserLabelClusterLabelStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(labelStructStructClass_1, labelStructStructCtor_1, newElement_0_label, newElement_0_value);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPUserLabelGeneratedCommandListAttributeCallback::CHIPUserLabelGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPUserLabelClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUserLabelGeneratedCommandListAttributeCallback::~CHIPUserLabelGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUserLabelGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPUserLabelGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUserLabelGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPUserLabelAcceptedCommandListAttributeCallback::CHIPUserLabelAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPUserLabelClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUserLabelAcceptedCommandListAttributeCallback::~CHIPUserLabelAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUserLabelAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPUserLabelAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUserLabelAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBooleanStateGeneratedCommandListAttributeCallback::CHIPBooleanStateGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPBooleanStateClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBooleanStateGeneratedCommandListAttributeCallback::~CHIPBooleanStateGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBooleanStateGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBooleanStateGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBooleanStateGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBooleanStateAcceptedCommandListAttributeCallback::CHIPBooleanStateAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPBooleanStateClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBooleanStateAcceptedCommandListAttributeCallback::~CHIPBooleanStateAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBooleanStateAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBooleanStateAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBooleanStateAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBooleanStateAttributeListAttributeCallback::CHIPBooleanStateAttributeListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPBooleanStateClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBooleanStateAttributeListAttributeCallback::~CHIPBooleanStateAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBooleanStateAttributeListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBooleanStateAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBooleanStateAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPModeSelectStandardNamespaceAttributeCallback::CHIPModeSelectStandardNamespaceAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPModeSelectClusterStandardNamespaceAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPModeSelectStandardNamespaceAttributeCallback::~CHIPModeSelectStandardNamespaceAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPModeSelectStandardNamespaceAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPModeSelectStandardNamespaceAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPModeSelectStandardNamespaceAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPModeSelectSupportedModesAttributeCallback::CHIPModeSelectSupportedModesAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPModeSelectClusterSupportedModesAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPModeSelectSupportedModesAttributeCallback::~CHIPModeSelectSupportedModesAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPModeSelectSupportedModesAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::ModeSelect::Structs::ModeOptionStruct::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPModeSelectSupportedModesAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPModeSelectSupportedModesAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_label;
        newElement_0_label = env->NewStringUTF(std::string(entry_0.label.data(), entry_0.label.size()).c_str());
        jobject newElement_0_mode;
        std::string newElement_0_modeClassName     = "java/lang/Integer";
        std::string newElement_0_modeCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_modeClassName.c_str(), newElement_0_modeCtorSignature.c_str(), entry_0.mode, newElement_0_mode);
        jobject newElement_0_semanticTags;
        chip::JniReferences::GetInstance().CreateArrayList(newElement_0_semanticTags);

        auto iter_newElement_0_semanticTags_2 = entry_0.semanticTags.begin();
        while (iter_newElement_0_semanticTags_2.Next())
        {
            auto & entry_2 = iter_newElement_0_semanticTags_2.GetValue();
            jobject newElement_2;
            jobject newElement_2_mfgCode;
            std::string newElement_2_mfgCodeClassName     = "java/lang/Integer";
            std::string newElement_2_mfgCodeCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_2_mfgCodeClassName.c_str(),
                                                                           newElement_2_mfgCodeCtorSignature.c_str(),
                                                                           entry_2.mfgCode, newElement_2_mfgCode);
            jobject newElement_2_value;
            std::string newElement_2_valueClassName     = "java/lang/Integer";
            std::string newElement_2_valueCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
                newElement_2_valueClassName.c_str(), newElement_2_valueCtorSignature.c_str(), entry_2.value, newElement_2_value);

            jclass semanticTagStructClass_3;
            err = chip::JniReferences::GetInstance().GetClassRef(
                env, "chip/devicecontroller/ChipStructs$ModeSelectClusterSemanticTag", semanticTagStructClass_3);
            if (err != CHIP_NO_ERROR)
            {
                ChipLogError(Zcl, "Could not find class ChipStructs$ModeSelectClusterSemanticTag");
                return;
            }
            jmethodID semanticTagStructCtor_3 =
                env->GetMethodID(semanticTagStructClass_3, "<init>", "(Ljava/lang/Integer;Ljava/lang/Integer;)V");
            if (semanticTagStructCtor_3 == nullptr)
            {
                ChipLogError(Zcl, "Could not find ChipStructs$ModeSelectClusterSemanticTag constructor");
                return;
            }

            newElement_2 =
                env->NewObject(semanticTagStructClass_3, semanticTagStructCtor_3, newElement_2_mfgCode, newElement_2_value);
            chip::JniReferences::GetInstance().AddToList(newElement_0_semanticTags, newElement_2);
        }

        jclass modeOptionStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$ModeSelectClusterModeOptionStruct", modeOptionStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$ModeSelectClusterModeOptionStruct");
            return;
        }
        jmethodID modeOptionStructStructCtor_1 = env->GetMethodID(modeOptionStructStructClass_1, "<init>",
                                                                  "(Ljava/lang/String;Ljava/lang/Integer;Ljava/util/ArrayList;)V");
        if (modeOptionStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$ModeSelectClusterModeOptionStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(modeOptionStructStructClass_1, modeOptionStructStructCtor_1, newElement_0_label,
                                      newElement_0_mode, newElement_0_semanticTags);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPModeSelectStartUpModeAttributeCallback::CHIPModeSelectStartUpModeAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPModeSelectClusterStartUpModeAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPModeSelectStartUpModeAttributeCallback::~CHIPModeSelectStartUpModeAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPModeSelectStartUpModeAttributeCallback::CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPModeSelectStartUpModeAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPModeSelectStartUpModeAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPModeSelectOnModeAttributeCallback::CHIPModeSelectOnModeAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPModeSelectClusterOnModeAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPModeSelectOnModeAttributeCallback::~CHIPModeSelectOnModeAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPModeSelectOnModeAttributeCallback::CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPModeSelectOnModeAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPModeSelectOnModeAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPModeSelectGeneratedCommandListAttributeCallback::CHIPModeSelectGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPModeSelectClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPModeSelectGeneratedCommandListAttributeCallback::~CHIPModeSelectGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPModeSelectGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPModeSelectGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPModeSelectGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPModeSelectAcceptedCommandListAttributeCallback::CHIPModeSelectAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPModeSelectClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPModeSelectAcceptedCommandListAttributeCallback::~CHIPModeSelectAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPModeSelectAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPModeSelectAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPModeSelectAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPModeSelectAttributeListAttributeCallback::CHIPModeSelectAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPModeSelectClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPModeSelectAttributeListAttributeCallback::~CHIPModeSelectAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPModeSelectAttributeListAttributeCallback::CallbackFn(void * context,
                                                              const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPModeSelectAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPModeSelectAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDoorLockLockStateAttributeCallback::CHIPDoorLockLockStateAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDoorLockClusterLockStateAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDoorLockLockStateAttributeCallback::~CHIPDoorLockLockStateAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDoorLockLockStateAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlLockState> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPDoorLockLockStateAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDoorLockLockStateAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(value.Value()), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPDoorLockDoorStateAttributeCallback::CHIPDoorLockDoorStateAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDoorLockClusterDoorStateAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDoorLockDoorStateAttributeCallback::~CHIPDoorLockDoorStateAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDoorLockDoorStateAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlDoorState> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPDoorLockDoorStateAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDoorLockDoorStateAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(value.Value()), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPDoorLockGeneratedCommandListAttributeCallback::CHIPDoorLockGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPDoorLockClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDoorLockGeneratedCommandListAttributeCallback::~CHIPDoorLockGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDoorLockGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDoorLockGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDoorLockGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDoorLockAcceptedCommandListAttributeCallback::CHIPDoorLockAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPDoorLockClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDoorLockAcceptedCommandListAttributeCallback::~CHIPDoorLockAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDoorLockAcceptedCommandListAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDoorLockAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDoorLockAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDoorLockAttributeListAttributeCallback::CHIPDoorLockAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDoorLockClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDoorLockAttributeListAttributeCallback::~CHIPDoorLockAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDoorLockAttributeListAttributeCallback::CallbackFn(void * context,
                                                            const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDoorLockAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDoorLockAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWindowCoveringCurrentPositionLiftAttributeCallback::CHIPWindowCoveringCurrentPositionLiftAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionLiftAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringCurrentPositionLiftAttributeCallback::~CHIPWindowCoveringCurrentPositionLiftAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringCurrentPositionLiftAttributeCallback::CallbackFn(void * context,
                                                                        const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWindowCoveringCurrentPositionLiftAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringCurrentPositionLiftAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWindowCoveringCurrentPositionTiltAttributeCallback::CHIPWindowCoveringCurrentPositionTiltAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionTiltAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringCurrentPositionTiltAttributeCallback::~CHIPWindowCoveringCurrentPositionTiltAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringCurrentPositionTiltAttributeCallback::CallbackFn(void * context,
                                                                        const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWindowCoveringCurrentPositionTiltAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringCurrentPositionTiltAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback::CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionLiftPercentageAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback::
    ~CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::Percent> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringCurrentPositionLiftPercentageAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback::CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionTiltPercentageAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback::
    ~CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::Percent> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringCurrentPositionTiltPercentageAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback::
    CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterTargetPositionLiftPercent100thsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback::
    ~CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::Percent100ths> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringTargetPositionLiftPercent100thsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback::
    CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterTargetPositionTiltPercent100thsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback::
    ~CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::Percent100ths> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringTargetPositionTiltPercent100thsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback::
    CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionLiftPercent100thsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback::
    ~CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::Percent100ths> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringCurrentPositionLiftPercent100thsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback::
    CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterCurrentPositionTiltPercent100thsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback::
    ~CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::Percent100ths> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringCurrentPositionTiltPercent100thsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPWindowCoveringGeneratedCommandListAttributeCallback::CHIPWindowCoveringGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringGeneratedCommandListAttributeCallback::~CHIPWindowCoveringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWindowCoveringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWindowCoveringAcceptedCommandListAttributeCallback::CHIPWindowCoveringAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringAcceptedCommandListAttributeCallback::~CHIPWindowCoveringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWindowCoveringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWindowCoveringAttributeListAttributeCallback::CHIPWindowCoveringAttributeListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringAttributeListAttributeCallback::~CHIPWindowCoveringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWindowCoveringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBarrierControlGeneratedCommandListAttributeCallback::CHIPBarrierControlGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBarrierControlClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBarrierControlGeneratedCommandListAttributeCallback::~CHIPBarrierControlGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBarrierControlGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBarrierControlGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBarrierControlGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBarrierControlAcceptedCommandListAttributeCallback::CHIPBarrierControlAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPBarrierControlClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBarrierControlAcceptedCommandListAttributeCallback::~CHIPBarrierControlAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBarrierControlAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBarrierControlAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBarrierControlAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBarrierControlAttributeListAttributeCallback::CHIPBarrierControlAttributeListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPBarrierControlClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBarrierControlAttributeListAttributeCallback::~CHIPBarrierControlAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBarrierControlAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBarrierControlAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBarrierControlAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPumpConfigurationAndControlMaxPressureAttributeCallback::CHIPPumpConfigurationAndControlMaxPressureAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxPressureAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMaxPressureAttributeCallback::~CHIPPumpConfigurationAndControlMaxPressureAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMaxPressureAttributeCallback::CallbackFn(void * context,
                                                                             const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMaxPressureAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMaxPressureAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback::CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxSpeedAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback::~CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback::CallbackFn(void * context,
                                                                          const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMaxSpeedAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMaxFlowAttributeCallback::CHIPPumpConfigurationAndControlMaxFlowAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxFlowAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMaxFlowAttributeCallback::~CHIPPumpConfigurationAndControlMaxFlowAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMaxFlowAttributeCallback::CallbackFn(void * context,
                                                                         const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMaxFlowAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMaxFlowAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback::CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMinConstPressureAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback::
    ~CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMinConstPressureAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback::CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxConstPressureAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback::
    ~CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMaxConstPressureAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback::CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMinCompPressureAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback::~CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMinCompPressureAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback::CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxCompPressureAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback::~CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMaxCompPressureAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback::CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMinConstSpeedAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback::~CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMinConstSpeedAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback::CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxConstSpeedAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback::~CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMaxConstSpeedAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback::CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMinConstFlowAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback::~CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMinConstFlowAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback::CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxConstFlowAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback::~CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMaxConstFlowAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMinConstTempAttributeCallback::CHIPPumpConfigurationAndControlMinConstTempAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMinConstTempAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMinConstTempAttributeCallback::~CHIPPumpConfigurationAndControlMinConstTempAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMinConstTempAttributeCallback::CallbackFn(void * context,
                                                                              const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMinConstTempAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMinConstTempAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback::CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterMaxConstTempAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback::~CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback::CallbackFn(void * context,
                                                                              const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlMaxConstTempAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlCapacityAttributeCallback::CHIPPumpConfigurationAndControlCapacityAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterCapacityAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlCapacityAttributeCallback::~CHIPPumpConfigurationAndControlCapacityAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlCapacityAttributeCallback::CallbackFn(void * context,
                                                                          const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlCapacityAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlCapacityAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlSpeedAttributeCallback::CHIPPumpConfigurationAndControlSpeedAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterSpeedAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlSpeedAttributeCallback::~CHIPPumpConfigurationAndControlSpeedAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlSpeedAttributeCallback::CallbackFn(void * context,
                                                                       const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlSpeedAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlSpeedAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback::
    CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterLifetimeRunningHoursAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback::
    ~CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlLifetimeRunningHoursAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlPowerAttributeCallback::CHIPPumpConfigurationAndControlPowerAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterPowerAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlPowerAttributeCallback::~CHIPPumpConfigurationAndControlPowerAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlPowerAttributeCallback::CallbackFn(void * context,
                                                                       const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlPowerAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlPowerAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback::
    CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterLifetimeEnergyConsumedAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback::
    ~CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlLifetimeEnergyConsumedAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback::
    CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback::
    ~CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback::
    CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback::
    ~CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPumpConfigurationAndControlAttributeListAttributeCallback::CHIPPumpConfigurationAndControlAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlAttributeListAttributeCallback::~CHIPPumpConfigurationAndControlAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPumpConfigurationAndControlAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThermostatLocalTemperatureAttributeCallback::CHIPThermostatLocalTemperatureAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterLocalTemperatureAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatLocalTemperatureAttributeCallback::~CHIPThermostatLocalTemperatureAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatLocalTemperatureAttributeCallback::CallbackFn(void * context,
                                                                 const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPThermostatLocalTemperatureAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatLocalTemperatureAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPThermostatAttributeListAttributeCallback::CHIPThermostatAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatAttributeListAttributeCallback::~CHIPThermostatAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatAttributeListAttributeCallback::CallbackFn(void * context,
                                                              const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThermostatAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFanControlPercentSettingAttributeCallback::CHIPFanControlPercentSettingAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFanControlClusterPercentSettingAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFanControlPercentSettingAttributeCallback::~CHIPFanControlPercentSettingAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFanControlPercentSettingAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPFanControlPercentSettingAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFanControlPercentSettingAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPFanControlSpeedSettingAttributeCallback::CHIPFanControlSpeedSettingAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFanControlClusterSpeedSettingAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFanControlSpeedSettingAttributeCallback::~CHIPFanControlSpeedSettingAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFanControlSpeedSettingAttributeCallback::CallbackFn(void * context, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPFanControlSpeedSettingAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFanControlSpeedSettingAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPFanControlGeneratedCommandListAttributeCallback::CHIPFanControlGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPFanControlClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFanControlGeneratedCommandListAttributeCallback::~CHIPFanControlGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFanControlGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFanControlGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFanControlGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFanControlAcceptedCommandListAttributeCallback::CHIPFanControlAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPFanControlClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFanControlAcceptedCommandListAttributeCallback::~CHIPFanControlAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFanControlAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFanControlAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFanControlAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFanControlAttributeListAttributeCallback::CHIPFanControlAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFanControlClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFanControlAttributeListAttributeCallback::~CHIPFanControlAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFanControlAttributeListAttributeCallback::CallbackFn(void * context,
                                                              const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFanControlAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFanControlAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback::
    CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatUserInterfaceConfigurationClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                       this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback::
    ~CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPThermostatUserInterfaceConfigurationGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback::
    CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatUserInterfaceConfigurationClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback::
    ~CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPThermostatUserInterfaceConfigurationAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback::
    CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatUserInterfaceConfigurationClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback::
    ~CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatUserInterfaceConfigurationAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPColorControlNumberOfPrimariesAttributeCallback::CHIPColorControlNumberOfPrimariesAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterNumberOfPrimariesAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlNumberOfPrimariesAttributeCallback::~CHIPColorControlNumberOfPrimariesAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlNumberOfPrimariesAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPColorControlNumberOfPrimariesAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlNumberOfPrimariesAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPColorControlPrimary1IntensityAttributeCallback::CHIPColorControlPrimary1IntensityAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterPrimary1IntensityAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlPrimary1IntensityAttributeCallback::~CHIPColorControlPrimary1IntensityAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlPrimary1IntensityAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPColorControlPrimary1IntensityAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlPrimary1IntensityAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPColorControlPrimary2IntensityAttributeCallback::CHIPColorControlPrimary2IntensityAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterPrimary2IntensityAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlPrimary2IntensityAttributeCallback::~CHIPColorControlPrimary2IntensityAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlPrimary2IntensityAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPColorControlPrimary2IntensityAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlPrimary2IntensityAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPColorControlPrimary3IntensityAttributeCallback::CHIPColorControlPrimary3IntensityAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterPrimary3IntensityAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlPrimary3IntensityAttributeCallback::~CHIPColorControlPrimary3IntensityAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlPrimary3IntensityAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPColorControlPrimary3IntensityAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlPrimary3IntensityAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPColorControlPrimary4IntensityAttributeCallback::CHIPColorControlPrimary4IntensityAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterPrimary4IntensityAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlPrimary4IntensityAttributeCallback::~CHIPColorControlPrimary4IntensityAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlPrimary4IntensityAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPColorControlPrimary4IntensityAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlPrimary4IntensityAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPColorControlPrimary5IntensityAttributeCallback::CHIPColorControlPrimary5IntensityAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterPrimary5IntensityAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlPrimary5IntensityAttributeCallback::~CHIPColorControlPrimary5IntensityAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlPrimary5IntensityAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPColorControlPrimary5IntensityAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlPrimary5IntensityAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPColorControlPrimary6IntensityAttributeCallback::CHIPColorControlPrimary6IntensityAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterPrimary6IntensityAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlPrimary6IntensityAttributeCallback::~CHIPColorControlPrimary6IntensityAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlPrimary6IntensityAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPColorControlPrimary6IntensityAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlPrimary6IntensityAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPColorControlColorPointRIntensityAttributeCallback::CHIPColorControlColorPointRIntensityAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterColorPointRIntensityAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlColorPointRIntensityAttributeCallback::~CHIPColorControlColorPointRIntensityAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlColorPointRIntensityAttributeCallback::CallbackFn(void * context,
                                                                       const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPColorControlColorPointRIntensityAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlColorPointRIntensityAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPColorControlColorPointGIntensityAttributeCallback::CHIPColorControlColorPointGIntensityAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterColorPointGIntensityAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlColorPointGIntensityAttributeCallback::~CHIPColorControlColorPointGIntensityAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlColorPointGIntensityAttributeCallback::CallbackFn(void * context,
                                                                       const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPColorControlColorPointGIntensityAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlColorPointGIntensityAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPColorControlColorPointBIntensityAttributeCallback::CHIPColorControlColorPointBIntensityAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterColorPointBIntensityAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlColorPointBIntensityAttributeCallback::~CHIPColorControlColorPointBIntensityAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlColorPointBIntensityAttributeCallback::CallbackFn(void * context,
                                                                       const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPColorControlColorPointBIntensityAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlColorPointBIntensityAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPColorControlGeneratedCommandListAttributeCallback::CHIPColorControlGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlGeneratedCommandListAttributeCallback::~CHIPColorControlGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPColorControlGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPColorControlAcceptedCommandListAttributeCallback::CHIPColorControlAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlAcceptedCommandListAttributeCallback::~CHIPColorControlAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPColorControlAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPColorControlAttributeListAttributeCallback::CHIPColorControlAttributeListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlAttributeListAttributeCallback::~CHIPColorControlAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlAttributeListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPColorControlAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback::CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBallastConfigurationClusterIntrinsicBalanceFactorAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback::~CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBallastConfigurationIntrinsicBalanceFactorAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback::CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBallastConfigurationClusterBallastFactorAdjustmentAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback::
    ~CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBallastConfigurationBallastFactorAdjustmentAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPBallastConfigurationLampRatedHoursAttributeCallback::CHIPBallastConfigurationLampRatedHoursAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBallastConfigurationClusterLampRatedHoursAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBallastConfigurationLampRatedHoursAttributeCallback::~CHIPBallastConfigurationLampRatedHoursAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBallastConfigurationLampRatedHoursAttributeCallback::CallbackFn(void * context,
                                                                         const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPBallastConfigurationLampRatedHoursAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBallastConfigurationLampRatedHoursAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPBallastConfigurationLampBurnHoursAttributeCallback::CHIPBallastConfigurationLampBurnHoursAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPBallastConfigurationClusterLampBurnHoursAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBallastConfigurationLampBurnHoursAttributeCallback::~CHIPBallastConfigurationLampBurnHoursAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBallastConfigurationLampBurnHoursAttributeCallback::CallbackFn(void * context,
                                                                        const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPBallastConfigurationLampBurnHoursAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBallastConfigurationLampBurnHoursAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback::CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBallastConfigurationClusterLampBurnHoursTripPointAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback::~CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBallastConfigurationLampBurnHoursTripPointAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPBallastConfigurationGeneratedCommandListAttributeCallback::CHIPBallastConfigurationGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBallastConfigurationClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBallastConfigurationGeneratedCommandListAttributeCallback::~CHIPBallastConfigurationGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBallastConfigurationGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBallastConfigurationGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBallastConfigurationGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBallastConfigurationAcceptedCommandListAttributeCallback::CHIPBallastConfigurationAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBallastConfigurationClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBallastConfigurationAcceptedCommandListAttributeCallback::~CHIPBallastConfigurationAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBallastConfigurationAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBallastConfigurationAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBallastConfigurationAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBallastConfigurationAttributeListAttributeCallback::CHIPBallastConfigurationAttributeListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPBallastConfigurationClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBallastConfigurationAttributeListAttributeCallback::~CHIPBallastConfigurationAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBallastConfigurationAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBallastConfigurationAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBallastConfigurationAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPIlluminanceMeasurementMeasuredValueAttributeCallback::CHIPIlluminanceMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPIlluminanceMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIlluminanceMeasurementMeasuredValueAttributeCallback::~CHIPIlluminanceMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIlluminanceMeasurementMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                          const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPIlluminanceMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIlluminanceMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback::CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPIlluminanceMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback::~CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                             const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIlluminanceMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback::CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPIlluminanceMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback::~CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                             const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIlluminanceMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback::CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPIlluminanceMeasurementClusterLightSensorTypeAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback::~CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback::CallbackFn(void * context,
                                                                            const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIlluminanceMeasurementLightSensorTypeAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback::CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPIlluminanceMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback::~CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIlluminanceMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback::CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPIlluminanceMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback::~CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIlluminanceMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPIlluminanceMeasurementAttributeListAttributeCallback::CHIPIlluminanceMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPIlluminanceMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIlluminanceMeasurementAttributeListAttributeCallback::~CHIPIlluminanceMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIlluminanceMeasurementAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPIlluminanceMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIlluminanceMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTemperatureMeasurementMeasuredValueAttributeCallback::CHIPTemperatureMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTemperatureMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTemperatureMeasurementMeasuredValueAttributeCallback::~CHIPTemperatureMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTemperatureMeasurementMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                          const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTemperatureMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTemperatureMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback::CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTemperatureMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback::~CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                             const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTemperatureMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback::CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTemperatureMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback::~CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                             const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTemperatureMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTemperatureMeasurementAttributeListAttributeCallback::CHIPTemperatureMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTemperatureMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTemperatureMeasurementAttributeListAttributeCallback::~CHIPTemperatureMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTemperatureMeasurementAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTemperatureMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTemperatureMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPressureMeasurementMeasuredValueAttributeCallback::CHIPPressureMeasurementMeasuredValueAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPPressureMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPressureMeasurementMeasuredValueAttributeCallback::~CHIPPressureMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPressureMeasurementMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                       const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPressureMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPressureMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPressureMeasurementMinMeasuredValueAttributeCallback::CHIPPressureMeasurementMinMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPressureMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPressureMeasurementMinMeasuredValueAttributeCallback::~CHIPPressureMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPressureMeasurementMinMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                          const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPressureMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPressureMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPressureMeasurementMaxMeasuredValueAttributeCallback::CHIPPressureMeasurementMaxMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPressureMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPressureMeasurementMaxMeasuredValueAttributeCallback::~CHIPPressureMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPressureMeasurementMaxMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                          const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPressureMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPressureMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPressureMeasurementScaledValueAttributeCallback::CHIPPressureMeasurementScaledValueAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPPressureMeasurementClusterScaledValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPressureMeasurementScaledValueAttributeCallback::~CHIPPressureMeasurementScaledValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPressureMeasurementScaledValueAttributeCallback::CallbackFn(void * context,
                                                                     const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPressureMeasurementScaledValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPressureMeasurementScaledValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPressureMeasurementMinScaledValueAttributeCallback::CHIPPressureMeasurementMinScaledValueAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPPressureMeasurementClusterMinScaledValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPressureMeasurementMinScaledValueAttributeCallback::~CHIPPressureMeasurementMinScaledValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPressureMeasurementMinScaledValueAttributeCallback::CallbackFn(void * context,
                                                                        const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPressureMeasurementMinScaledValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPressureMeasurementMinScaledValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPressureMeasurementMaxScaledValueAttributeCallback::CHIPPressureMeasurementMaxScaledValueAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPPressureMeasurementClusterMaxScaledValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPressureMeasurementMaxScaledValueAttributeCallback::~CHIPPressureMeasurementMaxScaledValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPressureMeasurementMaxScaledValueAttributeCallback::CallbackFn(void * context,
                                                                        const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPPressureMeasurementMaxScaledValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPressureMeasurementMaxScaledValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPPressureMeasurementAttributeListAttributeCallback::CHIPPressureMeasurementAttributeListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPPressureMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPressureMeasurementAttributeListAttributeCallback::~CHIPPressureMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPressureMeasurementAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPressureMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPressureMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFlowMeasurementMeasuredValueAttributeCallback::CHIPFlowMeasurementMeasuredValueAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPFlowMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFlowMeasurementMeasuredValueAttributeCallback::~CHIPFlowMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFlowMeasurementMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                   const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPFlowMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFlowMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPFlowMeasurementMinMeasuredValueAttributeCallback::CHIPFlowMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPFlowMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFlowMeasurementMinMeasuredValueAttributeCallback::~CHIPFlowMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFlowMeasurementMinMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                      const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPFlowMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFlowMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPFlowMeasurementMaxMeasuredValueAttributeCallback::CHIPFlowMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPFlowMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFlowMeasurementMaxMeasuredValueAttributeCallback::~CHIPFlowMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFlowMeasurementMaxMeasuredValueAttributeCallback::CallbackFn(void * context,
                                                                      const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPFlowMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFlowMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPFlowMeasurementGeneratedCommandListAttributeCallback::CHIPFlowMeasurementGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFlowMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFlowMeasurementGeneratedCommandListAttributeCallback::~CHIPFlowMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFlowMeasurementGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFlowMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFlowMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFlowMeasurementAcceptedCommandListAttributeCallback::CHIPFlowMeasurementAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFlowMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFlowMeasurementAcceptedCommandListAttributeCallback::~CHIPFlowMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFlowMeasurementAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFlowMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFlowMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFlowMeasurementAttributeListAttributeCallback::CHIPFlowMeasurementAttributeListAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPFlowMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFlowMeasurementAttributeListAttributeCallback::~CHIPFlowMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFlowMeasurementAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFlowMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFlowMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback::CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback::~CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRelativeHumidityMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback::CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRelativeHumidityMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback::CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRelativeHumidityMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback::
    CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRelativeHumidityMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback::
    CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRelativeHumidityMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPRelativeHumidityMeasurementAttributeListAttributeCallback::CHIPRelativeHumidityMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRelativeHumidityMeasurementAttributeListAttributeCallback::~CHIPRelativeHumidityMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRelativeHumidityMeasurementAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPRelativeHumidityMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRelativeHumidityMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOccupancySensingGeneratedCommandListAttributeCallback::CHIPOccupancySensingGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOccupancySensingClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOccupancySensingGeneratedCommandListAttributeCallback::~CHIPOccupancySensingGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOccupancySensingGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOccupancySensingGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOccupancySensingGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOccupancySensingAcceptedCommandListAttributeCallback::CHIPOccupancySensingAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOccupancySensingClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOccupancySensingAcceptedCommandListAttributeCallback::~CHIPOccupancySensingAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOccupancySensingAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOccupancySensingAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOccupancySensingAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOccupancySensingAttributeListAttributeCallback::CHIPOccupancySensingAttributeListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPOccupancySensingClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOccupancySensingAttributeListAttributeCallback::~CHIPOccupancySensingAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOccupancySensingAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOccupancySensingAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOccupancySensingAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWakeOnLanGeneratedCommandListAttributeCallback::CHIPWakeOnLanGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPWakeOnLanClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWakeOnLanGeneratedCommandListAttributeCallback::~CHIPWakeOnLanGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWakeOnLanGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWakeOnLanGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWakeOnLanGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWakeOnLanAcceptedCommandListAttributeCallback::CHIPWakeOnLanAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPWakeOnLanClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWakeOnLanAcceptedCommandListAttributeCallback::~CHIPWakeOnLanAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWakeOnLanAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWakeOnLanAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWakeOnLanAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWakeOnLanAttributeListAttributeCallback::CHIPWakeOnLanAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWakeOnLanClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWakeOnLanAttributeListAttributeCallback::~CHIPWakeOnLanAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWakeOnLanAttributeListAttributeCallback::CallbackFn(void * context,
                                                             const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWakeOnLanAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWakeOnLanAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChannelChannelListAttributeCallback::CHIPChannelChannelListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChannelClusterChannelListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChannelChannelListAttributeCallback::~CHIPChannelChannelListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChannelChannelListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::Channel::Structs::ChannelInfo::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPChannelChannelListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChannelChannelListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_majorNumber;
        std::string newElement_0_majorNumberClassName     = "java/lang/Integer";
        std::string newElement_0_majorNumberCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_majorNumberClassName.c_str(),
                                                                       newElement_0_majorNumberCtorSignature.c_str(),
                                                                       entry_0.majorNumber, newElement_0_majorNumber);
        jobject newElement_0_minorNumber;
        std::string newElement_0_minorNumberClassName     = "java/lang/Integer";
        std::string newElement_0_minorNumberCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_minorNumberClassName.c_str(),
                                                                       newElement_0_minorNumberCtorSignature.c_str(),
                                                                       entry_0.minorNumber, newElement_0_minorNumber);
        jobject newElement_0_name;
        if (!entry_0.name.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_name);
        }
        else
        {
            jobject newElement_0_nameInsideOptional;
            newElement_0_nameInsideOptional =
                env->NewStringUTF(std::string(entry_0.name.Value().data(), entry_0.name.Value().size()).c_str());
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_nameInsideOptional, newElement_0_name);
        }
        jobject newElement_0_callSign;
        if (!entry_0.callSign.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_callSign);
        }
        else
        {
            jobject newElement_0_callSignInsideOptional;
            newElement_0_callSignInsideOptional =
                env->NewStringUTF(std::string(entry_0.callSign.Value().data(), entry_0.callSign.Value().size()).c_str());
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_callSignInsideOptional, newElement_0_callSign);
        }
        jobject newElement_0_affiliateCallSign;
        if (!entry_0.affiliateCallSign.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_affiliateCallSign);
        }
        else
        {
            jobject newElement_0_affiliateCallSignInsideOptional;
            newElement_0_affiliateCallSignInsideOptional = env->NewStringUTF(
                std::string(entry_0.affiliateCallSign.Value().data(), entry_0.affiliateCallSign.Value().size()).c_str());
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_affiliateCallSignInsideOptional,
                                                              newElement_0_affiliateCallSign);
        }

        jclass channelInfoStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs$ChannelClusterChannelInfo",
                                                             channelInfoStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$ChannelClusterChannelInfo");
            return;
        }
        jmethodID channelInfoStructCtor_1 = env->GetMethodID(
            channelInfoStructClass_1, "<init>",
            "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V");
        if (channelInfoStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$ChannelClusterChannelInfo constructor");
            return;
        }

        newElement_0 =
            env->NewObject(channelInfoStructClass_1, channelInfoStructCtor_1, newElement_0_majorNumber, newElement_0_minorNumber,
                           newElement_0_name, newElement_0_callSign, newElement_0_affiliateCallSign);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChannelGeneratedCommandListAttributeCallback::CHIPChannelGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPChannelClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChannelGeneratedCommandListAttributeCallback::~CHIPChannelGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChannelGeneratedCommandListAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPChannelGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChannelGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChannelAcceptedCommandListAttributeCallback::CHIPChannelAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPChannelClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChannelAcceptedCommandListAttributeCallback::~CHIPChannelAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChannelAcceptedCommandListAttributeCallback::CallbackFn(void * context,
                                                                 const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPChannelAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChannelAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChannelAttributeListAttributeCallback::CHIPChannelAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChannelClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChannelAttributeListAttributeCallback::~CHIPChannelAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChannelAttributeListAttributeCallback::CallbackFn(void * context,
                                                           const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPChannelAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChannelAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTargetNavigatorTargetListAttributeCallback::CHIPTargetNavigatorTargetListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTargetNavigatorClusterTargetListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTargetNavigatorTargetListAttributeCallback::~CHIPTargetNavigatorTargetListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTargetNavigatorTargetListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::TargetNavigator::Structs::TargetInfo::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTargetNavigatorTargetListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTargetNavigatorTargetListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_identifier;
        std::string newElement_0_identifierClassName     = "java/lang/Integer";
        std::string newElement_0_identifierCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_identifierClassName.c_str(),
                                                                      newElement_0_identifierCtorSignature.c_str(),
                                                                      entry_0.identifier, newElement_0_identifier);
        jobject newElement_0_name;
        newElement_0_name = env->NewStringUTF(std::string(entry_0.name.data(), entry_0.name.size()).c_str());

        jclass targetInfoStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$TargetNavigatorClusterTargetInfo", targetInfoStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$TargetNavigatorClusterTargetInfo");
            return;
        }
        jmethodID targetInfoStructCtor_1 =
            env->GetMethodID(targetInfoStructClass_1, "<init>", "(Ljava/lang/Integer;Ljava/lang/String;)V");
        if (targetInfoStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$TargetNavigatorClusterTargetInfo constructor");
            return;
        }

        newElement_0 = env->NewObject(targetInfoStructClass_1, targetInfoStructCtor_1, newElement_0_identifier, newElement_0_name);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTargetNavigatorGeneratedCommandListAttributeCallback::CHIPTargetNavigatorGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTargetNavigatorClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTargetNavigatorGeneratedCommandListAttributeCallback::~CHIPTargetNavigatorGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTargetNavigatorGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTargetNavigatorGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTargetNavigatorGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTargetNavigatorAcceptedCommandListAttributeCallback::CHIPTargetNavigatorAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTargetNavigatorClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTargetNavigatorAcceptedCommandListAttributeCallback::~CHIPTargetNavigatorAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTargetNavigatorAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTargetNavigatorAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTargetNavigatorAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTargetNavigatorAttributeListAttributeCallback::CHIPTargetNavigatorAttributeListAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPTargetNavigatorClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTargetNavigatorAttributeListAttributeCallback::~CHIPTargetNavigatorAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTargetNavigatorAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTargetNavigatorAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTargetNavigatorAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPMediaPlaybackStartTimeAttributeCallback::CHIPMediaPlaybackStartTimeAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPMediaPlaybackClusterStartTimeAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaPlaybackStartTimeAttributeCallback::~CHIPMediaPlaybackStartTimeAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaPlaybackStartTimeAttributeCallback::CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPMediaPlaybackStartTimeAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaPlaybackStartTimeAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPMediaPlaybackDurationAttributeCallback::CHIPMediaPlaybackDurationAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPMediaPlaybackClusterDurationAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaPlaybackDurationAttributeCallback::~CHIPMediaPlaybackDurationAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaPlaybackDurationAttributeCallback::CallbackFn(void * context, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPMediaPlaybackDurationAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaPlaybackDurationAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPMediaPlaybackSeekRangeEndAttributeCallback::CHIPMediaPlaybackSeekRangeEndAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPMediaPlaybackClusterSeekRangeEndAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaPlaybackSeekRangeEndAttributeCallback::~CHIPMediaPlaybackSeekRangeEndAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaPlaybackSeekRangeEndAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPMediaPlaybackSeekRangeEndAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaPlaybackSeekRangeEndAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPMediaPlaybackSeekRangeStartAttributeCallback::CHIPMediaPlaybackSeekRangeStartAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPMediaPlaybackClusterSeekRangeStartAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaPlaybackSeekRangeStartAttributeCallback::~CHIPMediaPlaybackSeekRangeStartAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaPlaybackSeekRangeStartAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPMediaPlaybackSeekRangeStartAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaPlaybackSeekRangeStartAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPMediaPlaybackGeneratedCommandListAttributeCallback::CHIPMediaPlaybackGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPMediaPlaybackClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaPlaybackGeneratedCommandListAttributeCallback::~CHIPMediaPlaybackGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaPlaybackGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPMediaPlaybackGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaPlaybackGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPMediaPlaybackAcceptedCommandListAttributeCallback::CHIPMediaPlaybackAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPMediaPlaybackClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaPlaybackAcceptedCommandListAttributeCallback::~CHIPMediaPlaybackAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaPlaybackAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPMediaPlaybackAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaPlaybackAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPMediaPlaybackAttributeListAttributeCallback::CHIPMediaPlaybackAttributeListAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPMediaPlaybackClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaPlaybackAttributeListAttributeCallback::~CHIPMediaPlaybackAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaPlaybackAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPMediaPlaybackAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaPlaybackAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPMediaInputInputListAttributeCallback::CHIPMediaInputInputListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPMediaInputClusterInputListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaInputInputListAttributeCallback::~CHIPMediaInputInputListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaInputInputListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::MediaInput::Structs::InputInfo::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPMediaInputInputListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaInputInputListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_index;
        std::string newElement_0_indexClassName     = "java/lang/Integer";
        std::string newElement_0_indexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_indexClassName.c_str(), newElement_0_indexCtorSignature.c_str(), entry_0.index, newElement_0_index);
        jobject newElement_0_inputType;
        std::string newElement_0_inputTypeClassName     = "java/lang/Integer";
        std::string newElement_0_inputTypeCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_inputTypeClassName.c_str(), newElement_0_inputTypeCtorSignature.c_str(),
            static_cast<uint8_t>(entry_0.inputType), newElement_0_inputType);
        jobject newElement_0_name;
        newElement_0_name = env->NewStringUTF(std::string(entry_0.name.data(), entry_0.name.size()).c_str());
        jobject newElement_0_description;
        newElement_0_description = env->NewStringUTF(std::string(entry_0.description.data(), entry_0.description.size()).c_str());

        jclass inputInfoStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs$MediaInputClusterInputInfo",
                                                             inputInfoStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$MediaInputClusterInputInfo");
            return;
        }
        jmethodID inputInfoStructCtor_1 = env->GetMethodID(
            inputInfoStructClass_1, "<init>", "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;)V");
        if (inputInfoStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$MediaInputClusterInputInfo constructor");
            return;
        }

        newElement_0 = env->NewObject(inputInfoStructClass_1, inputInfoStructCtor_1, newElement_0_index, newElement_0_inputType,
                                      newElement_0_name, newElement_0_description);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPMediaInputGeneratedCommandListAttributeCallback::CHIPMediaInputGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPMediaInputClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaInputGeneratedCommandListAttributeCallback::~CHIPMediaInputGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaInputGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPMediaInputGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaInputGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPMediaInputAcceptedCommandListAttributeCallback::CHIPMediaInputAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPMediaInputClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaInputAcceptedCommandListAttributeCallback::~CHIPMediaInputAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaInputAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPMediaInputAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaInputAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPMediaInputAttributeListAttributeCallback::CHIPMediaInputAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPMediaInputClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaInputAttributeListAttributeCallback::~CHIPMediaInputAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaInputAttributeListAttributeCallback::CallbackFn(void * context,
                                                              const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPMediaInputAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaInputAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLowPowerGeneratedCommandListAttributeCallback::CHIPLowPowerGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPLowPowerClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLowPowerGeneratedCommandListAttributeCallback::~CHIPLowPowerGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLowPowerGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPLowPowerGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLowPowerGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLowPowerAcceptedCommandListAttributeCallback::CHIPLowPowerAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPLowPowerClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLowPowerAcceptedCommandListAttributeCallback::~CHIPLowPowerAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLowPowerAcceptedCommandListAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPLowPowerAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLowPowerAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLowPowerAttributeListAttributeCallback::CHIPLowPowerAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLowPowerClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLowPowerAttributeListAttributeCallback::~CHIPLowPowerAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLowPowerAttributeListAttributeCallback::CallbackFn(void * context,
                                                            const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPLowPowerAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLowPowerAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPKeypadInputGeneratedCommandListAttributeCallback::CHIPKeypadInputGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPKeypadInputClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPKeypadInputGeneratedCommandListAttributeCallback::~CHIPKeypadInputGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPKeypadInputGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPKeypadInputGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPKeypadInputGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPKeypadInputAcceptedCommandListAttributeCallback::CHIPKeypadInputAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPKeypadInputClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPKeypadInputAcceptedCommandListAttributeCallback::~CHIPKeypadInputAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPKeypadInputAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPKeypadInputAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPKeypadInputAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPKeypadInputAttributeListAttributeCallback::CHIPKeypadInputAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPKeypadInputClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPKeypadInputAttributeListAttributeCallback::~CHIPKeypadInputAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPKeypadInputAttributeListAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPKeypadInputAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPKeypadInputAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPContentLauncherAcceptHeaderAttributeCallback::CHIPContentLauncherAcceptHeaderAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPContentLauncherClusterAcceptHeaderAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPContentLauncherAcceptHeaderAttributeCallback::~CHIPContentLauncherAcceptHeaderAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPContentLauncherAcceptHeaderAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::DecodableList<chip::CharSpan> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPContentLauncherAcceptHeaderAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPContentLauncherAcceptHeaderAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        newElement_0 = env->NewStringUTF(std::string(entry_0.data(), entry_0.size()).c_str());
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPContentLauncherGeneratedCommandListAttributeCallback::CHIPContentLauncherGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPContentLauncherClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPContentLauncherGeneratedCommandListAttributeCallback::~CHIPContentLauncherGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPContentLauncherGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPContentLauncherGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPContentLauncherGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPContentLauncherAcceptedCommandListAttributeCallback::CHIPContentLauncherAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPContentLauncherClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPContentLauncherAcceptedCommandListAttributeCallback::~CHIPContentLauncherAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPContentLauncherAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPContentLauncherAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPContentLauncherAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPContentLauncherAttributeListAttributeCallback::CHIPContentLauncherAttributeListAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPContentLauncherClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPContentLauncherAttributeListAttributeCallback::~CHIPContentLauncherAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPContentLauncherAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPContentLauncherAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPContentLauncherAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAudioOutputOutputListAttributeCallback::CHIPAudioOutputOutputListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAudioOutputClusterOutputListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAudioOutputOutputListAttributeCallback::~CHIPAudioOutputOutputListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAudioOutputOutputListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::AudioOutput::Structs::OutputInfo::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAudioOutputOutputListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAudioOutputOutputListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_index;
        std::string newElement_0_indexClassName     = "java/lang/Integer";
        std::string newElement_0_indexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_indexClassName.c_str(), newElement_0_indexCtorSignature.c_str(), entry_0.index, newElement_0_index);
        jobject newElement_0_outputType;
        std::string newElement_0_outputTypeClassName     = "java/lang/Integer";
        std::string newElement_0_outputTypeCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_outputTypeClassName.c_str(), newElement_0_outputTypeCtorSignature.c_str(),
            static_cast<uint8_t>(entry_0.outputType), newElement_0_outputType);
        jobject newElement_0_name;
        newElement_0_name = env->NewStringUTF(std::string(entry_0.name.data(), entry_0.name.size()).c_str());

        jclass outputInfoStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs$AudioOutputClusterOutputInfo",
                                                             outputInfoStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$AudioOutputClusterOutputInfo");
            return;
        }
        jmethodID outputInfoStructCtor_1 =
            env->GetMethodID(outputInfoStructClass_1, "<init>", "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)V");
        if (outputInfoStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$AudioOutputClusterOutputInfo constructor");
            return;
        }

        newElement_0 = env->NewObject(outputInfoStructClass_1, outputInfoStructCtor_1, newElement_0_index, newElement_0_outputType,
                                      newElement_0_name);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAudioOutputGeneratedCommandListAttributeCallback::CHIPAudioOutputGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPAudioOutputClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAudioOutputGeneratedCommandListAttributeCallback::~CHIPAudioOutputGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAudioOutputGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAudioOutputGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAudioOutputGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAudioOutputAcceptedCommandListAttributeCallback::CHIPAudioOutputAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPAudioOutputClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAudioOutputAcceptedCommandListAttributeCallback::~CHIPAudioOutputAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAudioOutputAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAudioOutputAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAudioOutputAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAudioOutputAttributeListAttributeCallback::CHIPAudioOutputAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAudioOutputClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAudioOutputAttributeListAttributeCallback::~CHIPAudioOutputAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAudioOutputAttributeListAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAudioOutputAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAudioOutputAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPApplicationLauncherCatalogListAttributeCallback::CHIPApplicationLauncherCatalogListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPApplicationLauncherClusterCatalogListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPApplicationLauncherCatalogListAttributeCallback::~CHIPApplicationLauncherCatalogListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPApplicationLauncherCatalogListAttributeCallback::CallbackFn(void * context,
                                                                     const chip::app::DataModel::DecodableList<uint16_t> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPApplicationLauncherCatalogListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPApplicationLauncherCatalogListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPApplicationLauncherGeneratedCommandListAttributeCallback::CHIPApplicationLauncherGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPApplicationLauncherClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPApplicationLauncherGeneratedCommandListAttributeCallback::~CHIPApplicationLauncherGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPApplicationLauncherGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPApplicationLauncherGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPApplicationLauncherGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPApplicationLauncherAcceptedCommandListAttributeCallback::CHIPApplicationLauncherAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPApplicationLauncherClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPApplicationLauncherAcceptedCommandListAttributeCallback::~CHIPApplicationLauncherAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPApplicationLauncherAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPApplicationLauncherAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPApplicationLauncherAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPApplicationLauncherAttributeListAttributeCallback::CHIPApplicationLauncherAttributeListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPApplicationLauncherClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPApplicationLauncherAttributeListAttributeCallback::~CHIPApplicationLauncherAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPApplicationLauncherAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPApplicationLauncherAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPApplicationLauncherAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPApplicationBasicVendorIDAttributeCallback::CHIPApplicationBasicVendorIDAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPApplicationBasicClusterVendorIDAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPApplicationBasicVendorIDAttributeCallback::~CHIPApplicationBasicVendorIDAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPApplicationBasicVendorIDAttributeCallback::CallbackFn(void * context, chip::VendorId value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPApplicationBasicVendorIDAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPApplicationBasicVendorIDAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    std::string javaValueClassName     = "java/lang/Integer";
    std::string javaValueCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                   static_cast<uint16_t>(value), javaValue);

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPApplicationBasicAllowedVendorListAttributeCallback::CHIPApplicationBasicAllowedVendorListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPApplicationBasicClusterAllowedVendorListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPApplicationBasicAllowedVendorListAttributeCallback::~CHIPApplicationBasicAllowedVendorListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPApplicationBasicAllowedVendorListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::VendorId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPApplicationBasicAllowedVendorListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPApplicationBasicAllowedVendorListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), static_cast<uint16_t>(entry_0), newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPApplicationBasicGeneratedCommandListAttributeCallback::CHIPApplicationBasicGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPApplicationBasicClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPApplicationBasicGeneratedCommandListAttributeCallback::~CHIPApplicationBasicGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPApplicationBasicGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPApplicationBasicGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPApplicationBasicGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPApplicationBasicAcceptedCommandListAttributeCallback::CHIPApplicationBasicAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPApplicationBasicClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPApplicationBasicAcceptedCommandListAttributeCallback::~CHIPApplicationBasicAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPApplicationBasicAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPApplicationBasicAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPApplicationBasicAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPApplicationBasicAttributeListAttributeCallback::CHIPApplicationBasicAttributeListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPApplicationBasicClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPApplicationBasicAttributeListAttributeCallback::~CHIPApplicationBasicAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPApplicationBasicAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPApplicationBasicAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPApplicationBasicAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAccountLoginGeneratedCommandListAttributeCallback::CHIPAccountLoginGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPAccountLoginClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAccountLoginGeneratedCommandListAttributeCallback::~CHIPAccountLoginGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAccountLoginGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAccountLoginGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAccountLoginGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAccountLoginAcceptedCommandListAttributeCallback::CHIPAccountLoginAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPAccountLoginClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAccountLoginAcceptedCommandListAttributeCallback::~CHIPAccountLoginAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAccountLoginAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAccountLoginAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAccountLoginAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAccountLoginAttributeListAttributeCallback::CHIPAccountLoginAttributeListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPAccountLoginClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAccountLoginAttributeListAttributeCallback::~CHIPAccountLoginAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAccountLoginAttributeListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAccountLoginAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAccountLoginAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPElectricalMeasurementGeneratedCommandListAttributeCallback::CHIPElectricalMeasurementGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPElectricalMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPElectricalMeasurementGeneratedCommandListAttributeCallback::~CHIPElectricalMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPElectricalMeasurementGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPElectricalMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPElectricalMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPElectricalMeasurementAcceptedCommandListAttributeCallback::CHIPElectricalMeasurementAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPElectricalMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPElectricalMeasurementAcceptedCommandListAttributeCallback::~CHIPElectricalMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPElectricalMeasurementAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPElectricalMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPElectricalMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPElectricalMeasurementAttributeListAttributeCallback::CHIPElectricalMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPElectricalMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPElectricalMeasurementAttributeListAttributeCallback::~CHIPElectricalMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPElectricalMeasurementAttributeListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPElectricalMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPElectricalMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTestClusterListInt8uAttributeCallback::CHIPTestClusterListInt8uAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterListInt8uAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterListInt8uAttributeCallback::~CHIPTestClusterListInt8uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterListInt8uAttributeCallback::CallbackFn(void * context,
                                                           const chip::app::DataModel::DecodableList<uint8_t> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTestClusterListInt8uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterListInt8uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Integer";
        std::string newElement_0CtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0ClassName.c_str(),
                                                                      newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTestClusterListOctetStringAttributeCallback::CHIPTestClusterListOctetStringAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterListOctetStringAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterListOctetStringAttributeCallback::~CHIPTestClusterListOctetStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterListOctetStringAttributeCallback::CallbackFn(void * context,
                                                                 const chip::app::DataModel::DecodableList<chip::ByteSpan> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTestClusterListOctetStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterListOctetStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jbyteArray newElement_0ByteArray = env->NewByteArray(static_cast<jsize>(entry_0.size()));
        env->SetByteArrayRegion(newElement_0ByteArray, 0, static_cast<jsize>(entry_0.size()),
                                reinterpret_cast<const jbyte *>(entry_0.data()));
        newElement_0 = newElement_0ByteArray;
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTestClusterListStructOctetStringAttributeCallback::CHIPTestClusterListStructOctetStringAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterListStructOctetStringAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterListStructOctetStringAttributeCallback::~CHIPTestClusterListStructOctetStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterListStructOctetStringAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::TestCluster::Structs::TestListStructOctet::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTestClusterListStructOctetStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterListStructOctetStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_member1;
        std::string newElement_0_member1ClassName     = "java/lang/Long";
        std::string newElement_0_member1CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_0_member1ClassName.c_str(),
                                                                       newElement_0_member1CtorSignature.c_str(), entry_0.member1,
                                                                       newElement_0_member1);
        jobject newElement_0_member2;
        jbyteArray newElement_0_member2ByteArray = env->NewByteArray(static_cast<jsize>(entry_0.member2.size()));
        env->SetByteArrayRegion(newElement_0_member2ByteArray, 0, static_cast<jsize>(entry_0.member2.size()),
                                reinterpret_cast<const jbyte *>(entry_0.member2.data()));
        newElement_0_member2 = newElement_0_member2ByteArray;

        jclass testListStructOctetStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$TestClusterClusterTestListStructOctet", testListStructOctetStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$TestClusterClusterTestListStructOctet");
            return;
        }
        jmethodID testListStructOctetStructCtor_1 =
            env->GetMethodID(testListStructOctetStructClass_1, "<init>", "(Ljava/lang/Long;[B)V");
        if (testListStructOctetStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$TestClusterClusterTestListStructOctet constructor");
            return;
        }

        newElement_0 = env->NewObject(testListStructOctetStructClass_1, testListStructOctetStructCtor_1, newElement_0_member1,
                                      newElement_0_member2);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTestClusterVendorIdAttributeCallback::CHIPTestClusterVendorIdAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterVendorIdAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterVendorIdAttributeCallback::~CHIPTestClusterVendorIdAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterVendorIdAttributeCallback::CallbackFn(void * context, chip::VendorId value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterVendorIdAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterVendorIdAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    std::string javaValueClassName     = "java/lang/Integer";
    std::string javaValueCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                   static_cast<uint16_t>(value), javaValue);

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback::CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterListNullablesAndOptionalsStructAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback::~CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<
        chip::app::Clusters::TestCluster::Structs::NullablesAndOptionalsStruct::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterListNullablesAndOptionalsStructAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_nullableInt;
        if (entry_0.nullableInt.IsNull())
        {
            newElement_0_nullableInt = nullptr;
        }
        else
        {
            std::string newElement_0_nullableIntClassName     = "java/lang/Integer";
            std::string newElement_0_nullableIntCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_nullableIntClassName.c_str(),
                                                                           newElement_0_nullableIntCtorSignature.c_str(),
                                                                           entry_0.nullableInt.Value(), newElement_0_nullableInt);
        }
        jobject newElement_0_optionalInt;
        if (!entry_0.optionalInt.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_optionalInt);
        }
        else
        {
            jobject newElement_0_optionalIntInsideOptional;
            std::string newElement_0_optionalIntInsideOptionalClassName     = "java/lang/Integer";
            std::string newElement_0_optionalIntInsideOptionalCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
                newElement_0_optionalIntInsideOptionalClassName.c_str(),
                newElement_0_optionalIntInsideOptionalCtorSignature.c_str(), entry_0.optionalInt.Value(),
                newElement_0_optionalIntInsideOptional);
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_optionalIntInsideOptional, newElement_0_optionalInt);
        }
        jobject newElement_0_nullableOptionalInt;
        if (!entry_0.nullableOptionalInt.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_nullableOptionalInt);
        }
        else
        {
            jobject newElement_0_nullableOptionalIntInsideOptional;
            if (entry_0.nullableOptionalInt.Value().IsNull())
            {
                newElement_0_nullableOptionalIntInsideOptional = nullptr;
            }
            else
            {
                std::string newElement_0_nullableOptionalIntInsideOptionalClassName     = "java/lang/Integer";
                std::string newElement_0_nullableOptionalIntInsideOptionalCtorSignature = "(I)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
                    newElement_0_nullableOptionalIntInsideOptionalClassName.c_str(),
                    newElement_0_nullableOptionalIntInsideOptionalCtorSignature.c_str(),
                    entry_0.nullableOptionalInt.Value().Value(), newElement_0_nullableOptionalIntInsideOptional);
            }
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_nullableOptionalIntInsideOptional,
                                                              newElement_0_nullableOptionalInt);
        }
        jobject newElement_0_nullableString;
        if (entry_0.nullableString.IsNull())
        {
            newElement_0_nullableString = nullptr;
        }
        else
        {
            newElement_0_nullableString = env->NewStringUTF(
                std::string(entry_0.nullableString.Value().data(), entry_0.nullableString.Value().size()).c_str());
        }
        jobject newElement_0_optionalString;
        if (!entry_0.optionalString.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_optionalString);
        }
        else
        {
            jobject newElement_0_optionalStringInsideOptional;
            newElement_0_optionalStringInsideOptional = env->NewStringUTF(
                std::string(entry_0.optionalString.Value().data(), entry_0.optionalString.Value().size()).c_str());
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_optionalStringInsideOptional,
                                                              newElement_0_optionalString);
        }
        jobject newElement_0_nullableOptionalString;
        if (!entry_0.nullableOptionalString.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_nullableOptionalString);
        }
        else
        {
            jobject newElement_0_nullableOptionalStringInsideOptional;
            if (entry_0.nullableOptionalString.Value().IsNull())
            {
                newElement_0_nullableOptionalStringInsideOptional = nullptr;
            }
            else
            {
                newElement_0_nullableOptionalStringInsideOptional =
                    env->NewStringUTF(std::string(entry_0.nullableOptionalString.Value().Value().data(),
                                                  entry_0.nullableOptionalString.Value().Value().size())
                                          .c_str());
            }
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_nullableOptionalStringInsideOptional,
                                                              newElement_0_nullableOptionalString);
        }
        jobject newElement_0_nullableStruct;
        if (entry_0.nullableStruct.IsNull())
        {
            newElement_0_nullableStruct = nullptr;
        }
        else
        {
            jobject newElement_0_nullableStruct_a;
            std::string newElement_0_nullableStruct_aClassName     = "java/lang/Integer";
            std::string newElement_0_nullableStruct_aCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_0_nullableStruct_aClassName.c_str(), newElement_0_nullableStruct_aCtorSignature.c_str(),
                entry_0.nullableStruct.Value().a, newElement_0_nullableStruct_a);
            jobject newElement_0_nullableStruct_b;
            std::string newElement_0_nullableStruct_bClassName     = "java/lang/Boolean";
            std::string newElement_0_nullableStruct_bCtorSignature = "(Z)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
                newElement_0_nullableStruct_bClassName.c_str(), newElement_0_nullableStruct_bCtorSignature.c_str(),
                entry_0.nullableStruct.Value().b, newElement_0_nullableStruct_b);
            jobject newElement_0_nullableStruct_c;
            std::string newElement_0_nullableStruct_cClassName     = "java/lang/Integer";
            std::string newElement_0_nullableStruct_cCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_0_nullableStruct_cClassName.c_str(), newElement_0_nullableStruct_cCtorSignature.c_str(),
                static_cast<uint8_t>(entry_0.nullableStruct.Value().c), newElement_0_nullableStruct_c);
            jobject newElement_0_nullableStruct_d;
            jbyteArray newElement_0_nullableStruct_dByteArray =
                env->NewByteArray(static_cast<jsize>(entry_0.nullableStruct.Value().d.size()));
            env->SetByteArrayRegion(newElement_0_nullableStruct_dByteArray, 0,
                                    static_cast<jsize>(entry_0.nullableStruct.Value().d.size()),
                                    reinterpret_cast<const jbyte *>(entry_0.nullableStruct.Value().d.data()));
            newElement_0_nullableStruct_d = newElement_0_nullableStruct_dByteArray;
            jobject newElement_0_nullableStruct_e;
            newElement_0_nullableStruct_e = env->NewStringUTF(
                std::string(entry_0.nullableStruct.Value().e.data(), entry_0.nullableStruct.Value().e.size()).c_str());
            jobject newElement_0_nullableStruct_f;
            std::string newElement_0_nullableStruct_fClassName     = "java/lang/Integer";
            std::string newElement_0_nullableStruct_fCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_0_nullableStruct_fClassName.c_str(), newElement_0_nullableStruct_fCtorSignature.c_str(),
                entry_0.nullableStruct.Value().f.Raw(), newElement_0_nullableStruct_f);
            jobject newElement_0_nullableStruct_g;
            std::string newElement_0_nullableStruct_gClassName     = "java/lang/Float";
            std::string newElement_0_nullableStruct_gCtorSignature = "(F)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<float>(
                newElement_0_nullableStruct_gClassName.c_str(), newElement_0_nullableStruct_gCtorSignature.c_str(),
                entry_0.nullableStruct.Value().g, newElement_0_nullableStruct_g);
            jobject newElement_0_nullableStruct_h;
            std::string newElement_0_nullableStruct_hClassName     = "java/lang/Double";
            std::string newElement_0_nullableStruct_hCtorSignature = "(D)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<double>(
                newElement_0_nullableStruct_hClassName.c_str(), newElement_0_nullableStruct_hCtorSignature.c_str(),
                entry_0.nullableStruct.Value().h, newElement_0_nullableStruct_h);

            jclass simpleStructStructClass_3;
            err = chip::JniReferences::GetInstance().GetClassRef(
                env, "chip/devicecontroller/ChipStructs$TestClusterClusterSimpleStruct", simpleStructStructClass_3);
            if (err != CHIP_NO_ERROR)
            {
                ChipLogError(Zcl, "Could not find class ChipStructs$TestClusterClusterSimpleStruct");
                return;
            }
            jmethodID simpleStructStructCtor_3 =
                env->GetMethodID(simpleStructStructClass_3, "<init>",
                                 "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/"
                                 "Integer;Ljava/lang/Float;Ljava/lang/Double;)V");
            if (simpleStructStructCtor_3 == nullptr)
            {
                ChipLogError(Zcl, "Could not find ChipStructs$TestClusterClusterSimpleStruct constructor");
                return;
            }

            newElement_0_nullableStruct = env->NewObject(
                simpleStructStructClass_3, simpleStructStructCtor_3, newElement_0_nullableStruct_a, newElement_0_nullableStruct_b,
                newElement_0_nullableStruct_c, newElement_0_nullableStruct_d, newElement_0_nullableStruct_e,
                newElement_0_nullableStruct_f, newElement_0_nullableStruct_g, newElement_0_nullableStruct_h);
        }
        jobject newElement_0_optionalStruct;
        if (!entry_0.optionalStruct.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_optionalStruct);
        }
        else
        {
            jobject newElement_0_optionalStructInsideOptional;
            jobject newElement_0_optionalStructInsideOptional_a;
            std::string newElement_0_optionalStructInsideOptional_aClassName     = "java/lang/Integer";
            std::string newElement_0_optionalStructInsideOptional_aCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_0_optionalStructInsideOptional_aClassName.c_str(),
                newElement_0_optionalStructInsideOptional_aCtorSignature.c_str(), entry_0.optionalStruct.Value().a,
                newElement_0_optionalStructInsideOptional_a);
            jobject newElement_0_optionalStructInsideOptional_b;
            std::string newElement_0_optionalStructInsideOptional_bClassName     = "java/lang/Boolean";
            std::string newElement_0_optionalStructInsideOptional_bCtorSignature = "(Z)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
                newElement_0_optionalStructInsideOptional_bClassName.c_str(),
                newElement_0_optionalStructInsideOptional_bCtorSignature.c_str(), entry_0.optionalStruct.Value().b,
                newElement_0_optionalStructInsideOptional_b);
            jobject newElement_0_optionalStructInsideOptional_c;
            std::string newElement_0_optionalStructInsideOptional_cClassName     = "java/lang/Integer";
            std::string newElement_0_optionalStructInsideOptional_cCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_0_optionalStructInsideOptional_cClassName.c_str(),
                newElement_0_optionalStructInsideOptional_cCtorSignature.c_str(),
                static_cast<uint8_t>(entry_0.optionalStruct.Value().c), newElement_0_optionalStructInsideOptional_c);
            jobject newElement_0_optionalStructInsideOptional_d;
            jbyteArray newElement_0_optionalStructInsideOptional_dByteArray =
                env->NewByteArray(static_cast<jsize>(entry_0.optionalStruct.Value().d.size()));
            env->SetByteArrayRegion(newElement_0_optionalStructInsideOptional_dByteArray, 0,
                                    static_cast<jsize>(entry_0.optionalStruct.Value().d.size()),
                                    reinterpret_cast<const jbyte *>(entry_0.optionalStruct.Value().d.data()));
            newElement_0_optionalStructInsideOptional_d = newElement_0_optionalStructInsideOptional_dByteArray;
            jobject newElement_0_optionalStructInsideOptional_e;
            newElement_0_optionalStructInsideOptional_e = env->NewStringUTF(
                std::string(entry_0.optionalStruct.Value().e.data(), entry_0.optionalStruct.Value().e.size()).c_str());
            jobject newElement_0_optionalStructInsideOptional_f;
            std::string newElement_0_optionalStructInsideOptional_fClassName     = "java/lang/Integer";
            std::string newElement_0_optionalStructInsideOptional_fCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_0_optionalStructInsideOptional_fClassName.c_str(),
                newElement_0_optionalStructInsideOptional_fCtorSignature.c_str(), entry_0.optionalStruct.Value().f.Raw(),
                newElement_0_optionalStructInsideOptional_f);
            jobject newElement_0_optionalStructInsideOptional_g;
            std::string newElement_0_optionalStructInsideOptional_gClassName     = "java/lang/Float";
            std::string newElement_0_optionalStructInsideOptional_gCtorSignature = "(F)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<float>(
                newElement_0_optionalStructInsideOptional_gClassName.c_str(),
                newElement_0_optionalStructInsideOptional_gCtorSignature.c_str(), entry_0.optionalStruct.Value().g,
                newElement_0_optionalStructInsideOptional_g);
            jobject newElement_0_optionalStructInsideOptional_h;
            std::string newElement_0_optionalStructInsideOptional_hClassName     = "java/lang/Double";
            std::string newElement_0_optionalStructInsideOptional_hCtorSignature = "(D)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<double>(
                newElement_0_optionalStructInsideOptional_hClassName.c_str(),
                newElement_0_optionalStructInsideOptional_hCtorSignature.c_str(), entry_0.optionalStruct.Value().h,
                newElement_0_optionalStructInsideOptional_h);

            jclass simpleStructStructClass_3;
            err = chip::JniReferences::GetInstance().GetClassRef(
                env, "chip/devicecontroller/ChipStructs$TestClusterClusterSimpleStruct", simpleStructStructClass_3);
            if (err != CHIP_NO_ERROR)
            {
                ChipLogError(Zcl, "Could not find class ChipStructs$TestClusterClusterSimpleStruct");
                return;
            }
            jmethodID simpleStructStructCtor_3 =
                env->GetMethodID(simpleStructStructClass_3, "<init>",
                                 "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/"
                                 "Integer;Ljava/lang/Float;Ljava/lang/Double;)V");
            if (simpleStructStructCtor_3 == nullptr)
            {
                ChipLogError(Zcl, "Could not find ChipStructs$TestClusterClusterSimpleStruct constructor");
                return;
            }

            newElement_0_optionalStructInsideOptional =
                env->NewObject(simpleStructStructClass_3, simpleStructStructCtor_3, newElement_0_optionalStructInsideOptional_a,
                               newElement_0_optionalStructInsideOptional_b, newElement_0_optionalStructInsideOptional_c,
                               newElement_0_optionalStructInsideOptional_d, newElement_0_optionalStructInsideOptional_e,
                               newElement_0_optionalStructInsideOptional_f, newElement_0_optionalStructInsideOptional_g,
                               newElement_0_optionalStructInsideOptional_h);
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_optionalStructInsideOptional,
                                                              newElement_0_optionalStruct);
        }
        jobject newElement_0_nullableOptionalStruct;
        if (!entry_0.nullableOptionalStruct.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_nullableOptionalStruct);
        }
        else
        {
            jobject newElement_0_nullableOptionalStructInsideOptional;
            if (entry_0.nullableOptionalStruct.Value().IsNull())
            {
                newElement_0_nullableOptionalStructInsideOptional = nullptr;
            }
            else
            {
                jobject newElement_0_nullableOptionalStructInsideOptional_a;
                std::string newElement_0_nullableOptionalStructInsideOptional_aClassName     = "java/lang/Integer";
                std::string newElement_0_nullableOptionalStructInsideOptional_aCtorSignature = "(I)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                    newElement_0_nullableOptionalStructInsideOptional_aClassName.c_str(),
                    newElement_0_nullableOptionalStructInsideOptional_aCtorSignature.c_str(),
                    entry_0.nullableOptionalStruct.Value().Value().a, newElement_0_nullableOptionalStructInsideOptional_a);
                jobject newElement_0_nullableOptionalStructInsideOptional_b;
                std::string newElement_0_nullableOptionalStructInsideOptional_bClassName     = "java/lang/Boolean";
                std::string newElement_0_nullableOptionalStructInsideOptional_bCtorSignature = "(Z)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
                    newElement_0_nullableOptionalStructInsideOptional_bClassName.c_str(),
                    newElement_0_nullableOptionalStructInsideOptional_bCtorSignature.c_str(),
                    entry_0.nullableOptionalStruct.Value().Value().b, newElement_0_nullableOptionalStructInsideOptional_b);
                jobject newElement_0_nullableOptionalStructInsideOptional_c;
                std::string newElement_0_nullableOptionalStructInsideOptional_cClassName     = "java/lang/Integer";
                std::string newElement_0_nullableOptionalStructInsideOptional_cCtorSignature = "(I)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                    newElement_0_nullableOptionalStructInsideOptional_cClassName.c_str(),
                    newElement_0_nullableOptionalStructInsideOptional_cCtorSignature.c_str(),
                    static_cast<uint8_t>(entry_0.nullableOptionalStruct.Value().Value().c),
                    newElement_0_nullableOptionalStructInsideOptional_c);
                jobject newElement_0_nullableOptionalStructInsideOptional_d;
                jbyteArray newElement_0_nullableOptionalStructInsideOptional_dByteArray =
                    env->NewByteArray(static_cast<jsize>(entry_0.nullableOptionalStruct.Value().Value().d.size()));
                env->SetByteArrayRegion(newElement_0_nullableOptionalStructInsideOptional_dByteArray, 0,
                                        static_cast<jsize>(entry_0.nullableOptionalStruct.Value().Value().d.size()),
                                        reinterpret_cast<const jbyte *>(entry_0.nullableOptionalStruct.Value().Value().d.data()));
                newElement_0_nullableOptionalStructInsideOptional_d = newElement_0_nullableOptionalStructInsideOptional_dByteArray;
                jobject newElement_0_nullableOptionalStructInsideOptional_e;
                newElement_0_nullableOptionalStructInsideOptional_e =
                    env->NewStringUTF(std::string(entry_0.nullableOptionalStruct.Value().Value().e.data(),
                                                  entry_0.nullableOptionalStruct.Value().Value().e.size())
                                          .c_str());
                jobject newElement_0_nullableOptionalStructInsideOptional_f;
                std::string newElement_0_nullableOptionalStructInsideOptional_fClassName     = "java/lang/Integer";
                std::string newElement_0_nullableOptionalStructInsideOptional_fCtorSignature = "(I)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                    newElement_0_nullableOptionalStructInsideOptional_fClassName.c_str(),
                    newElement_0_nullableOptionalStructInsideOptional_fCtorSignature.c_str(),
                    entry_0.nullableOptionalStruct.Value().Value().f.Raw(), newElement_0_nullableOptionalStructInsideOptional_f);
                jobject newElement_0_nullableOptionalStructInsideOptional_g;
                std::string newElement_0_nullableOptionalStructInsideOptional_gClassName     = "java/lang/Float";
                std::string newElement_0_nullableOptionalStructInsideOptional_gCtorSignature = "(F)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<float>(
                    newElement_0_nullableOptionalStructInsideOptional_gClassName.c_str(),
                    newElement_0_nullableOptionalStructInsideOptional_gCtorSignature.c_str(),
                    entry_0.nullableOptionalStruct.Value().Value().g, newElement_0_nullableOptionalStructInsideOptional_g);
                jobject newElement_0_nullableOptionalStructInsideOptional_h;
                std::string newElement_0_nullableOptionalStructInsideOptional_hClassName     = "java/lang/Double";
                std::string newElement_0_nullableOptionalStructInsideOptional_hCtorSignature = "(D)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<double>(
                    newElement_0_nullableOptionalStructInsideOptional_hClassName.c_str(),
                    newElement_0_nullableOptionalStructInsideOptional_hCtorSignature.c_str(),
                    entry_0.nullableOptionalStruct.Value().Value().h, newElement_0_nullableOptionalStructInsideOptional_h);

                jclass simpleStructStructClass_4;
                err = chip::JniReferences::GetInstance().GetClassRef(
                    env, "chip/devicecontroller/ChipStructs$TestClusterClusterSimpleStruct", simpleStructStructClass_4);
                if (err != CHIP_NO_ERROR)
                {
                    ChipLogError(Zcl, "Could not find class ChipStructs$TestClusterClusterSimpleStruct");
                    return;
                }
                jmethodID simpleStructStructCtor_4 =
                    env->GetMethodID(simpleStructStructClass_4, "<init>",
                                     "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/"
                                     "Integer;Ljava/lang/Float;Ljava/lang/Double;)V");
                if (simpleStructStructCtor_4 == nullptr)
                {
                    ChipLogError(Zcl, "Could not find ChipStructs$TestClusterClusterSimpleStruct constructor");
                    return;
                }

                newElement_0_nullableOptionalStructInsideOptional = env->NewObject(
                    simpleStructStructClass_4, simpleStructStructCtor_4, newElement_0_nullableOptionalStructInsideOptional_a,
                    newElement_0_nullableOptionalStructInsideOptional_b, newElement_0_nullableOptionalStructInsideOptional_c,
                    newElement_0_nullableOptionalStructInsideOptional_d, newElement_0_nullableOptionalStructInsideOptional_e,
                    newElement_0_nullableOptionalStructInsideOptional_f, newElement_0_nullableOptionalStructInsideOptional_g,
                    newElement_0_nullableOptionalStructInsideOptional_h);
            }
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_nullableOptionalStructInsideOptional,
                                                              newElement_0_nullableOptionalStruct);
        }
        jobject newElement_0_nullableList;
        if (entry_0.nullableList.IsNull())
        {
            newElement_0_nullableList = nullptr;
        }
        else
        {
            chip::JniReferences::GetInstance().CreateArrayList(newElement_0_nullableList);

            auto iter_newElement_0_nullableList_3 = entry_0.nullableList.Value().begin();
            while (iter_newElement_0_nullableList_3.Next())
            {
                auto & entry_3 = iter_newElement_0_nullableList_3.GetValue();
                jobject newElement_3;
                std::string newElement_3ClassName     = "java/lang/Integer";
                std::string newElement_3CtorSignature = "(I)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                    newElement_3ClassName.c_str(), newElement_3CtorSignature.c_str(), static_cast<uint8_t>(entry_3), newElement_3);
                chip::JniReferences::GetInstance().AddToList(newElement_0_nullableList, newElement_3);
            }
        }
        jobject newElement_0_optionalList;
        if (!entry_0.optionalList.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_optionalList);
        }
        else
        {
            jobject newElement_0_optionalListInsideOptional;
            chip::JniReferences::GetInstance().CreateArrayList(newElement_0_optionalListInsideOptional);

            auto iter_newElement_0_optionalListInsideOptional_3 = entry_0.optionalList.Value().begin();
            while (iter_newElement_0_optionalListInsideOptional_3.Next())
            {
                auto & entry_3 = iter_newElement_0_optionalListInsideOptional_3.GetValue();
                jobject newElement_3;
                std::string newElement_3ClassName     = "java/lang/Integer";
                std::string newElement_3CtorSignature = "(I)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                    newElement_3ClassName.c_str(), newElement_3CtorSignature.c_str(), static_cast<uint8_t>(entry_3), newElement_3);
                chip::JniReferences::GetInstance().AddToList(newElement_0_optionalListInsideOptional, newElement_3);
            }
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_optionalListInsideOptional, newElement_0_optionalList);
        }
        jobject newElement_0_nullableOptionalList;
        if (!entry_0.nullableOptionalList.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_nullableOptionalList);
        }
        else
        {
            jobject newElement_0_nullableOptionalListInsideOptional;
            if (entry_0.nullableOptionalList.Value().IsNull())
            {
                newElement_0_nullableOptionalListInsideOptional = nullptr;
            }
            else
            {
                chip::JniReferences::GetInstance().CreateArrayList(newElement_0_nullableOptionalListInsideOptional);

                auto iter_newElement_0_nullableOptionalListInsideOptional_4 = entry_0.nullableOptionalList.Value().Value().begin();
                while (iter_newElement_0_nullableOptionalListInsideOptional_4.Next())
                {
                    auto & entry_4 = iter_newElement_0_nullableOptionalListInsideOptional_4.GetValue();
                    jobject newElement_4;
                    std::string newElement_4ClassName     = "java/lang/Integer";
                    std::string newElement_4CtorSignature = "(I)V";
                    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_4ClassName.c_str(),
                                                                                  newElement_4CtorSignature.c_str(),
                                                                                  static_cast<uint8_t>(entry_4), newElement_4);
                    chip::JniReferences::GetInstance().AddToList(newElement_0_nullableOptionalListInsideOptional, newElement_4);
                }
            }
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_nullableOptionalListInsideOptional,
                                                              newElement_0_nullableOptionalList);
        }

        jclass nullablesAndOptionalsStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$TestClusterClusterNullablesAndOptionalsStruct",
            nullablesAndOptionalsStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$TestClusterClusterNullablesAndOptionalsStruct");
            return;
        }
        jmethodID nullablesAndOptionalsStructStructCtor_1 =
            env->GetMethodID(nullablesAndOptionalsStructStructClass_1, "<init>",
                             "(Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;Ljava/lang/String;Ljava/util/"
                             "Optional;Ljava/util/Optional;Lchip/devicecontroller/ChipStructs$TestClusterClusterSimpleStruct;Ljava/"
                             "util/Optional;Ljava/util/Optional;Ljava/util/ArrayList;Ljava/util/Optional;Ljava/util/Optional;)V");
        if (nullablesAndOptionalsStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$TestClusterClusterNullablesAndOptionalsStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(nullablesAndOptionalsStructStructClass_1, nullablesAndOptionalsStructStructCtor_1,
                                      newElement_0_nullableInt, newElement_0_optionalInt, newElement_0_nullableOptionalInt,
                                      newElement_0_nullableString, newElement_0_optionalString, newElement_0_nullableOptionalString,
                                      newElement_0_nullableStruct, newElement_0_optionalStruct, newElement_0_nullableOptionalStruct,
                                      newElement_0_nullableList, newElement_0_optionalList, newElement_0_nullableOptionalList);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTestClusterListLongOctetStringAttributeCallback::CHIPTestClusterListLongOctetStringAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterListLongOctetStringAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterListLongOctetStringAttributeCallback::~CHIPTestClusterListLongOctetStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterListLongOctetStringAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::ByteSpan> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTestClusterListLongOctetStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterListLongOctetStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jbyteArray newElement_0ByteArray = env->NewByteArray(static_cast<jsize>(entry_0.size()));
        env->SetByteArrayRegion(newElement_0ByteArray, 0, static_cast<jsize>(entry_0.size()),
                                reinterpret_cast<const jbyte *>(entry_0.data()));
        newElement_0 = newElement_0ByteArray;
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTestClusterListFabricScopedAttributeCallback::CHIPTestClusterListFabricScopedAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterListFabricScopedAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterListFabricScopedAttributeCallback::~CHIPTestClusterListFabricScopedAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterListFabricScopedAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::TestCluster::Structs::TestFabricScoped::DecodableType> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTestClusterListFabricScopedAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterListFabricScopedAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_fabricSensitiveInt8u;
        std::string newElement_0_fabricSensitiveInt8uClassName     = "java/lang/Integer";
        std::string newElement_0_fabricSensitiveInt8uCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_fabricSensitiveInt8uClassName.c_str(), newElement_0_fabricSensitiveInt8uCtorSignature.c_str(),
            entry_0.fabricSensitiveInt8u, newElement_0_fabricSensitiveInt8u);
        jobject newElement_0_optionalFabricSensitiveInt8u;
        if (!entry_0.optionalFabricSensitiveInt8u.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_optionalFabricSensitiveInt8u);
        }
        else
        {
            jobject newElement_0_optionalFabricSensitiveInt8uInsideOptional;
            std::string newElement_0_optionalFabricSensitiveInt8uInsideOptionalClassName     = "java/lang/Integer";
            std::string newElement_0_optionalFabricSensitiveInt8uInsideOptionalCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_0_optionalFabricSensitiveInt8uInsideOptionalClassName.c_str(),
                newElement_0_optionalFabricSensitiveInt8uInsideOptionalCtorSignature.c_str(),
                entry_0.optionalFabricSensitiveInt8u.Value(), newElement_0_optionalFabricSensitiveInt8uInsideOptional);
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_optionalFabricSensitiveInt8uInsideOptional,
                                                              newElement_0_optionalFabricSensitiveInt8u);
        }
        jobject newElement_0_nullableFabricSensitiveInt8u;
        if (entry_0.nullableFabricSensitiveInt8u.IsNull())
        {
            newElement_0_nullableFabricSensitiveInt8u = nullptr;
        }
        else
        {
            std::string newElement_0_nullableFabricSensitiveInt8uClassName     = "java/lang/Integer";
            std::string newElement_0_nullableFabricSensitiveInt8uCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_0_nullableFabricSensitiveInt8uClassName.c_str(),
                newElement_0_nullableFabricSensitiveInt8uCtorSignature.c_str(), entry_0.nullableFabricSensitiveInt8u.Value(),
                newElement_0_nullableFabricSensitiveInt8u);
        }
        jobject newElement_0_nullableOptionalFabricSensitiveInt8u;
        if (!entry_0.nullableOptionalFabricSensitiveInt8u.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_nullableOptionalFabricSensitiveInt8u);
        }
        else
        {
            jobject newElement_0_nullableOptionalFabricSensitiveInt8uInsideOptional;
            if (entry_0.nullableOptionalFabricSensitiveInt8u.Value().IsNull())
            {
                newElement_0_nullableOptionalFabricSensitiveInt8uInsideOptional = nullptr;
            }
            else
            {
                std::string newElement_0_nullableOptionalFabricSensitiveInt8uInsideOptionalClassName     = "java/lang/Integer";
                std::string newElement_0_nullableOptionalFabricSensitiveInt8uInsideOptionalCtorSignature = "(I)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                    newElement_0_nullableOptionalFabricSensitiveInt8uInsideOptionalClassName.c_str(),
                    newElement_0_nullableOptionalFabricSensitiveInt8uInsideOptionalCtorSignature.c_str(),
                    entry_0.nullableOptionalFabricSensitiveInt8u.Value().Value(),
                    newElement_0_nullableOptionalFabricSensitiveInt8uInsideOptional);
            }
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_nullableOptionalFabricSensitiveInt8uInsideOptional,
                                                              newElement_0_nullableOptionalFabricSensitiveInt8u);
        }
        jobject newElement_0_fabricSensitiveCharString;
        newElement_0_fabricSensitiveCharString = env->NewStringUTF(
            std::string(entry_0.fabricSensitiveCharString.data(), entry_0.fabricSensitiveCharString.size()).c_str());
        jobject newElement_0_fabricSensitiveStruct;
        jobject newElement_0_fabricSensitiveStruct_a;
        std::string newElement_0_fabricSensitiveStruct_aClassName     = "java/lang/Integer";
        std::string newElement_0_fabricSensitiveStruct_aCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_fabricSensitiveStruct_aClassName.c_str(), newElement_0_fabricSensitiveStruct_aCtorSignature.c_str(),
            entry_0.fabricSensitiveStruct.a, newElement_0_fabricSensitiveStruct_a);
        jobject newElement_0_fabricSensitiveStruct_b;
        std::string newElement_0_fabricSensitiveStruct_bClassName     = "java/lang/Boolean";
        std::string newElement_0_fabricSensitiveStruct_bCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
            newElement_0_fabricSensitiveStruct_bClassName.c_str(), newElement_0_fabricSensitiveStruct_bCtorSignature.c_str(),
            entry_0.fabricSensitiveStruct.b, newElement_0_fabricSensitiveStruct_b);
        jobject newElement_0_fabricSensitiveStruct_c;
        std::string newElement_0_fabricSensitiveStruct_cClassName     = "java/lang/Integer";
        std::string newElement_0_fabricSensitiveStruct_cCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_fabricSensitiveStruct_cClassName.c_str(), newElement_0_fabricSensitiveStruct_cCtorSignature.c_str(),
            static_cast<uint8_t>(entry_0.fabricSensitiveStruct.c), newElement_0_fabricSensitiveStruct_c);
        jobject newElement_0_fabricSensitiveStruct_d;
        jbyteArray newElement_0_fabricSensitiveStruct_dByteArray =
            env->NewByteArray(static_cast<jsize>(entry_0.fabricSensitiveStruct.d.size()));
        env->SetByteArrayRegion(newElement_0_fabricSensitiveStruct_dByteArray, 0,
                                static_cast<jsize>(entry_0.fabricSensitiveStruct.d.size()),
                                reinterpret_cast<const jbyte *>(entry_0.fabricSensitiveStruct.d.data()));
        newElement_0_fabricSensitiveStruct_d = newElement_0_fabricSensitiveStruct_dByteArray;
        jobject newElement_0_fabricSensitiveStruct_e;
        newElement_0_fabricSensitiveStruct_e =
            env->NewStringUTF(std::string(entry_0.fabricSensitiveStruct.e.data(), entry_0.fabricSensitiveStruct.e.size()).c_str());
        jobject newElement_0_fabricSensitiveStruct_f;
        std::string newElement_0_fabricSensitiveStruct_fClassName     = "java/lang/Integer";
        std::string newElement_0_fabricSensitiveStruct_fCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_fabricSensitiveStruct_fClassName.c_str(), newElement_0_fabricSensitiveStruct_fCtorSignature.c_str(),
            entry_0.fabricSensitiveStruct.f.Raw(), newElement_0_fabricSensitiveStruct_f);
        jobject newElement_0_fabricSensitiveStruct_g;
        std::string newElement_0_fabricSensitiveStruct_gClassName     = "java/lang/Float";
        std::string newElement_0_fabricSensitiveStruct_gCtorSignature = "(F)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<float>(
            newElement_0_fabricSensitiveStruct_gClassName.c_str(), newElement_0_fabricSensitiveStruct_gCtorSignature.c_str(),
            entry_0.fabricSensitiveStruct.g, newElement_0_fabricSensitiveStruct_g);
        jobject newElement_0_fabricSensitiveStruct_h;
        std::string newElement_0_fabricSensitiveStruct_hClassName     = "java/lang/Double";
        std::string newElement_0_fabricSensitiveStruct_hCtorSignature = "(D)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<double>(
            newElement_0_fabricSensitiveStruct_hClassName.c_str(), newElement_0_fabricSensitiveStruct_hCtorSignature.c_str(),
            entry_0.fabricSensitiveStruct.h, newElement_0_fabricSensitiveStruct_h);

        jclass simpleStructStructClass_2;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$TestClusterClusterSimpleStruct", simpleStructStructClass_2);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$TestClusterClusterSimpleStruct");
            return;
        }
        jmethodID simpleStructStructCtor_2 =
            env->GetMethodID(simpleStructStructClass_2, "<init>",
                             "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/"
                             "Integer;Ljava/lang/Float;Ljava/lang/Double;)V");
        if (simpleStructStructCtor_2 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$TestClusterClusterSimpleStruct constructor");
            return;
        }

        newElement_0_fabricSensitiveStruct = env->NewObject(
            simpleStructStructClass_2, simpleStructStructCtor_2, newElement_0_fabricSensitiveStruct_a,
            newElement_0_fabricSensitiveStruct_b, newElement_0_fabricSensitiveStruct_c, newElement_0_fabricSensitiveStruct_d,
            newElement_0_fabricSensitiveStruct_e, newElement_0_fabricSensitiveStruct_f, newElement_0_fabricSensitiveStruct_g,
            newElement_0_fabricSensitiveStruct_h);
        jobject newElement_0_fabricSensitiveInt8uList;
        chip::JniReferences::GetInstance().CreateArrayList(newElement_0_fabricSensitiveInt8uList);

        auto iter_newElement_0_fabricSensitiveInt8uList_2 = entry_0.fabricSensitiveInt8uList.begin();
        while (iter_newElement_0_fabricSensitiveInt8uList_2.Next())
        {
            auto & entry_2 = iter_newElement_0_fabricSensitiveInt8uList_2.GetValue();
            jobject newElement_2;
            std::string newElement_2ClassName     = "java/lang/Integer";
            std::string newElement_2CtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_2ClassName.c_str(),
                                                                          newElement_2CtorSignature.c_str(), entry_2, newElement_2);
            chip::JniReferences::GetInstance().AddToList(newElement_0_fabricSensitiveInt8uList, newElement_2);
        }
        jobject newElement_0_fabricIndex;
        std::string newElement_0_fabricIndexClassName     = "java/lang/Integer";
        std::string newElement_0_fabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_fabricIndexClassName.c_str(),
                                                                      newElement_0_fabricIndexCtorSignature.c_str(),
                                                                      entry_0.fabricIndex, newElement_0_fabricIndex);

        jclass testFabricScopedStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$TestClusterClusterTestFabricScoped", testFabricScopedStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$TestClusterClusterTestFabricScoped");
            return;
        }
        jmethodID testFabricScopedStructCtor_1 = env->GetMethodID(
            testFabricScopedStructClass_1, "<init>",
            "(Ljava/lang/Integer;Ljava/util/Optional;Ljava/lang/Integer;Ljava/util/Optional;Ljava/lang/String;Lchip/"
            "devicecontroller/ChipStructs$TestClusterClusterSimpleStruct;Ljava/util/ArrayList;Ljava/lang/Integer;)V");
        if (testFabricScopedStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$TestClusterClusterTestFabricScoped constructor");
            return;
        }

        newElement_0 =
            env->NewObject(testFabricScopedStructClass_1, testFabricScopedStructCtor_1, newElement_0_fabricSensitiveInt8u,
                           newElement_0_optionalFabricSensitiveInt8u, newElement_0_nullableFabricSensitiveInt8u,
                           newElement_0_nullableOptionalFabricSensitiveInt8u, newElement_0_fabricSensitiveCharString,
                           newElement_0_fabricSensitiveStruct, newElement_0_fabricSensitiveInt8uList, newElement_0_fabricIndex);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTestClusterNullableBooleanAttributeCallback::CHIPTestClusterNullableBooleanAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableBooleanAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableBooleanAttributeCallback::~CHIPTestClusterNullableBooleanAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableBooleanAttributeCallback::CallbackFn(void * context, const chip::app::DataModel::Nullable<bool> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableBooleanAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableBooleanAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Boolean;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Boolean";
        std::string javaValueCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                   value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableBitmap8AttributeCallback::CHIPTestClusterNullableBitmap8AttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableBitmap8AttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableBitmap8AttributeCallback::~CHIPTestClusterNullableBitmap8AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableBitmap8AttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap>> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableBitmap8AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableBitmap8AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value().Raw(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableBitmap16AttributeCallback::CHIPTestClusterNullableBitmap16AttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableBitmap16AttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableBitmap16AttributeCallback::~CHIPTestClusterNullableBitmap16AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableBitmap16AttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap>> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableBitmap16AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableBitmap16AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value().Raw(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableBitmap32AttributeCallback::CHIPTestClusterNullableBitmap32AttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableBitmap32AttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableBitmap32AttributeCallback::~CHIPTestClusterNullableBitmap32AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableBitmap32AttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap>> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableBitmap32AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableBitmap32AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value().Raw(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableBitmap64AttributeCallback::CHIPTestClusterNullableBitmap64AttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableBitmap64AttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableBitmap64AttributeCallback::~CHIPTestClusterNullableBitmap64AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableBitmap64AttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap>> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableBitmap64AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableBitmap64AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value().Raw(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt8uAttributeCallback::CHIPTestClusterNullableInt8uAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt8uAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt8uAttributeCallback::~CHIPTestClusterNullableInt8uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt8uAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt8uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt8uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt16uAttributeCallback::CHIPTestClusterNullableInt16uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt16uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt16uAttributeCallback::~CHIPTestClusterNullableInt16uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt16uAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt16uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt16uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt24uAttributeCallback::CHIPTestClusterNullableInt24uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt24uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt24uAttributeCallback::~CHIPTestClusterNullableInt24uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt24uAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt24uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt24uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt32uAttributeCallback::CHIPTestClusterNullableInt32uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt32uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt32uAttributeCallback::~CHIPTestClusterNullableInt32uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt32uAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<uint32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt32uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt32uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt40uAttributeCallback::CHIPTestClusterNullableInt40uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt40uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt40uAttributeCallback::~CHIPTestClusterNullableInt40uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt40uAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt40uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt40uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt48uAttributeCallback::CHIPTestClusterNullableInt48uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt48uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt48uAttributeCallback::~CHIPTestClusterNullableInt48uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt48uAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt48uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt48uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt56uAttributeCallback::CHIPTestClusterNullableInt56uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt56uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt56uAttributeCallback::~CHIPTestClusterNullableInt56uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt56uAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt56uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt56uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt64uAttributeCallback::CHIPTestClusterNullableInt64uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt64uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt64uAttributeCallback::~CHIPTestClusterNullableInt64uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt64uAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<uint64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt64uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt64uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt8sAttributeCallback::CHIPTestClusterNullableInt8sAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt8sAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt8sAttributeCallback::~CHIPTestClusterNullableInt8sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt8sAttributeCallback::CallbackFn(void * context, const chip::app::DataModel::Nullable<int8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt8sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt8sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                     value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt16sAttributeCallback::CHIPTestClusterNullableInt16sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt16sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt16sAttributeCallback::~CHIPTestClusterNullableInt16sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt16sAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt16sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt16sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt24sAttributeCallback::CHIPTestClusterNullableInt24sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt24sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt24sAttributeCallback::~CHIPTestClusterNullableInt24sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt24sAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<int32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt24sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt24sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt32sAttributeCallback::CHIPTestClusterNullableInt32sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt32sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt32sAttributeCallback::~CHIPTestClusterNullableInt32sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt32sAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<int32_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt32sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt32sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int32_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt40sAttributeCallback::CHIPTestClusterNullableInt40sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt40sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt40sAttributeCallback::~CHIPTestClusterNullableInt40sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt40sAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<int64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt40sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt40sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt48sAttributeCallback::CHIPTestClusterNullableInt48sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt48sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt48sAttributeCallback::~CHIPTestClusterNullableInt48sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt48sAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<int64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt48sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt48sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt56sAttributeCallback::CHIPTestClusterNullableInt56sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt56sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt56sAttributeCallback::~CHIPTestClusterNullableInt56sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt56sAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<int64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt56sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt56sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableInt64sAttributeCallback::CHIPTestClusterNullableInt64sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableInt64sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableInt64sAttributeCallback::~CHIPTestClusterNullableInt64sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableInt64sAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<int64_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableInt64sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableInt64sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Long";
        std::string javaValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int64_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableEnum8AttributeCallback::CHIPTestClusterNullableEnum8AttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableEnum8AttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableEnum8AttributeCallback::~CHIPTestClusterNullableEnum8AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableEnum8AttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableEnum8AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableEnum8AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableEnum16AttributeCallback::CHIPTestClusterNullableEnum16AttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableEnum16AttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableEnum16AttributeCallback::~CHIPTestClusterNullableEnum16AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableEnum16AttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableEnum16AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableEnum16AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableFloatSingleAttributeCallback::CHIPTestClusterNullableFloatSingleAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableFloatSingleAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableFloatSingleAttributeCallback::~CHIPTestClusterNullableFloatSingleAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableFloatSingleAttributeCallback::CallbackFn(void * context,
                                                                     const chip::app::DataModel::Nullable<float> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableFloatSingleAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableFloatSingleAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Float;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Float";
        std::string javaValueCtorSignature = "(F)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<float>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                    value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableFloatDoubleAttributeCallback::CHIPTestClusterNullableFloatDoubleAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableFloatDoubleAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableFloatDoubleAttributeCallback::~CHIPTestClusterNullableFloatDoubleAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableFloatDoubleAttributeCallback::CallbackFn(void * context,
                                                                     const chip::app::DataModel::Nullable<double> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableFloatDoubleAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableFloatDoubleAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Double;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Double";
        std::string javaValueCtorSignature = "(D)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<double>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                     value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableOctetStringAttributeCallback::CHIPTestClusterNullableOctetStringAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableOctetStringAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableOctetStringAttributeCallback::~CHIPTestClusterNullableOctetStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableOctetStringAttributeCallback::CallbackFn(void * context,
                                                                     const chip::app::DataModel::Nullable<chip::ByteSpan> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableOctetStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableOctetStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "([B)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        jbyteArray javaValueByteArray = env->NewByteArray(static_cast<jsize>(value.Value().size()));
        env->SetByteArrayRegion(javaValueByteArray, 0, static_cast<jsize>(value.Value().size()),
                                reinterpret_cast<const jbyte *>(value.Value().data()));
        javaValue = javaValueByteArray;
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableCharStringAttributeCallback::CHIPTestClusterNullableCharStringAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableCharStringAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableCharStringAttributeCallback::~CHIPTestClusterNullableCharStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableCharStringAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::Nullable<chip::CharSpan> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableCharStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableCharStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/String;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        javaValue = env->NewStringUTF(std::string(value.Value().data(), value.Value().size()).c_str());
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableEnumAttrAttributeCallback::CHIPTestClusterNullableEnumAttrAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableEnumAttrAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableEnumAttrAttributeCallback::~CHIPTestClusterNullableEnumAttrAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableEnumAttrAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::app::Clusters::TestCluster::SimpleEnum> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableEnumAttrAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableEnumAttrAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(value.Value()), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback::CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableRangeRestrictedInt8uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback::~CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback::CallbackFn(void * context,
                                                                              const chip::app::DataModel::Nullable<uint8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableRangeRestrictedInt8uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback::CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableRangeRestrictedInt8sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback::~CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback::CallbackFn(void * context,
                                                                              const chip::app::DataModel::Nullable<int8_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableRangeRestrictedInt8sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int8_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                     value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback::CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableRangeRestrictedInt16uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback::~CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableRangeRestrictedInt16uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                       value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback::CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterNullableRangeRestrictedInt16sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback::~CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<int16_t> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
    std::unique_ptr<CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterNullableRangeRestrictedInt16sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject javaValue;
    if (value.IsNull())
    {
        javaValue = nullptr;
    }
    else
    {
        std::string javaValueClassName     = "java/lang/Integer";
        std::string javaValueCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(javaValueClassName.c_str(), javaValueCtorSignature.c_str(),
                                                                      value.Value(), javaValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPTestClusterGeneratedCommandListAttributeCallback::CHIPTestClusterGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterGeneratedCommandListAttributeCallback::~CHIPTestClusterGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterGeneratedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTestClusterGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTestClusterAcceptedCommandListAttributeCallback::CHIPTestClusterAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterAcceptedCommandListAttributeCallback::~CHIPTestClusterAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterAcceptedCommandListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::CommandId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTestClusterAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTestClusterAttributeListAttributeCallback::CHIPTestClusterAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTestClusterClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTestClusterAttributeListAttributeCallback::~CHIPTestClusterAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTestClusterAttributeListAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::DecodableList<chip::AttributeId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTestClusterAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTestClusterAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}
