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

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

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

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

void CHIPActionsActionListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::Actions::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<CHIPActionsActionListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPActionsActionListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != 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.Raw(), newElement_0_supportedCommands);
        jobject newElement_0_state;
        std::string newElement_0_stateClassName     = "java/lang/Integer";
        std::string newElement_0_stateCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_stateClassName.c_str(),
                                                                      newElement_0_stateCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(entry_0.state), newElement_0_state);

        jclass actionStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs$ActionsClusterActionStruct",
                                                             actionStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$ActionsClusterActionStruct");
            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$ActionsClusterActionStruct 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_state);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

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

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

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

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

void CHIPActionsEndpointListsAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::Actions::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<CHIPActionsEndpointListsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPActionsEndpointListsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != 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$ActionsClusterEndpointListStruct", endpointListStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$ActionsClusterEndpointListStruct");
            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$ActionsClusterEndpointListStruct 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);
}

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

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

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

void CHIPActionsGeneratedCommandListAttributeCallback::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<CHIPActionsGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPActionsGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != 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);
}

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

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

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

void CHIPActionsAcceptedCommandListAttributeCallback::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<CHIPActionsAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPActionsAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != 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);
}

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

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

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

void CHIPActionsAttributeListAttributeCallback::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<CHIPActionsAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPActionsAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != 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);
}

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

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

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

void CHIPThreadNetworkDiagnosticsChannelPage0MaskAttributeCallback::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<CHIPThreadNetworkDiagnosticsChannelPage0MaskAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThreadNetworkDiagnosticsChannelPage0MaskAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(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);
}
