/*
 *
 *    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 <jni/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 <lib/support/SafeInt.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"));

    VerifyOrReturn(chip::CanCastTo<uint32_t>(value.size()), ChipLogError(Zcl, "Value too long"));
    jbyteArray valueArr = env->NewByteArray(static_cast<uint32_t>(value.size()));
    env->ExceptionClear();
    env->SetByteArrayRegion(valueArr, 0, static_cast<uint32_t>(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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    jobject arrayListObj;
    chip::JniReferences::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_deviceType;
        std::string newElement_0_deviceTypeClassName     = "java/lang/Long";
        std::string newElement_0_deviceTypeCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0_deviceTypeClassName.c_str(),
                                                                       newElement_0_deviceTypeCtorSignature.c_str(),
                                                                       entry_0.deviceType, newElement_0_deviceType);
        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 deviceTypeStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$DescriptorClusterDeviceTypeStruct", deviceTypeStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$DescriptorClusterDeviceTypeStruct");
            return;
        }
        jmethodID deviceTypeStructStructCtor_1 =
            env->GetMethodID(deviceTypeStructStructClass_1, "<init>", "(Ljava/lang/Long;Ljava/lang/Integer;)V");
        if (deviceTypeStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$DescriptorClusterDeviceTypeStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(deviceTypeStructStructClass_1, deviceTypeStructStructCtor_1, newElement_0_deviceType,
                                      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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::AccessControlEntryStruct::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 accessControlTargetStructStructClass_4;
                err = chip::JniReferences::GetInstance().GetClassRef(
                    env, "chip/devicecontroller/ChipStructs$AccessControlClusterAccessControlTargetStruct",
                    accessControlTargetStructStructClass_4);
                if (err != CHIP_NO_ERROR)
                {
                    ChipLogError(Zcl, "Could not find class ChipStructs$AccessControlClusterAccessControlTargetStruct");
                    return;
                }
                jmethodID accessControlTargetStructStructCtor_4 = env->GetMethodID(
                    accessControlTargetStructStructClass_4, "<init>", "(Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Long;)V");
                if (accessControlTargetStructStructCtor_4 == nullptr)
                {
                    ChipLogError(Zcl, "Could not find ChipStructs$AccessControlClusterAccessControlTargetStruct constructor");
                    return;
                }

                newElement_3 = env->NewObject(accessControlTargetStructStructClass_4, accessControlTargetStructStructCtor_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 accessControlEntryStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$AccessControlClusterAccessControlEntryStruct",
            accessControlEntryStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$AccessControlClusterAccessControlEntryStruct");
            return;
        }
        jmethodID accessControlEntryStructStructCtor_1 = env->GetMethodID(
            accessControlEntryStructStructClass_1, "<init>",
            "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/ArrayList;Ljava/util/ArrayList;Ljava/lang/Integer;)V");
        if (accessControlEntryStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$AccessControlClusterAccessControlEntryStruct constructor");
            return;
        }

        newElement_0 =
            env->NewObject(accessControlEntryStructStructClass_1, accessControlEntryStructStructCtor_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::AccessControlExtensionStruct::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 accessControlExtensionStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$AccessControlClusterAccessControlExtensionStruct",
            accessControlExtensionStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$AccessControlClusterAccessControlExtensionStruct");
            return;
        }
        jmethodID accessControlExtensionStructStructCtor_1 =
            env->GetMethodID(accessControlExtensionStructStructClass_1, "<init>", "([BLjava/lang/Integer;)V");
        if (accessControlExtensionStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$AccessControlClusterAccessControlExtensionStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(accessControlExtensionStructStructClass_1, accessControlExtensionStructStructCtor_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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.name, newElement_0_name));
        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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.name, newElement_0_name));
        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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0, newElement_0));
        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);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::CalendarTypeEnum> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = 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);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::WiredFaultEnum> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = 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::BatFaultEnum> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = 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::BatChargeFaultEnum> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = 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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::NetworkInterface::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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.name, newElement_0_name));
        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 networkInterfaceStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$GeneralDiagnosticsClusterNetworkInterface", networkInterfaceStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$GeneralDiagnosticsClusterNetworkInterface");
            return;
        }
        jmethodID networkInterfaceStructCtor_1 =
            env->GetMethodID(networkInterfaceStructClass_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 (networkInterfaceStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$GeneralDiagnosticsClusterNetworkInterface constructor");
            return;
        }

        newElement_0 = env->NewObject(networkInterfaceStructClass_1, networkInterfaceStructCtor_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<chip::app::Clusters::GeneralDiagnostics::HardwareFaultEnum> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = 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(), static_cast<uint8_t>(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<chip::app::Clusters::GeneralDiagnostics::RadioFaultEnum> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = 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(), static_cast<uint8_t>(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<chip::app::Clusters::GeneralDiagnostics::NetworkFaultEnum> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = 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(), static_cast<uint8_t>(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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::ThreadMetricsStruct::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;
            LogErrorOnFailure(
                chip::JniReferences::GetInstance().CharToStringUTF(entry_0.name.Value(), newElement_0_nameInsideOptional));
            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 threadMetricsStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$SoftwareDiagnosticsClusterThreadMetricsStruct",
            threadMetricsStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$SoftwareDiagnosticsClusterThreadMetricsStruct");
            return;
        }
        jmethodID threadMetricsStructStructCtor_1 =
            env->GetMethodID(threadMetricsStructStructClass_1, "<init>",
                             "(Ljava/lang/Long;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V");
        if (threadMetricsStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$SoftwareDiagnosticsClusterThreadMetricsStruct constructor");
            return;
        }

        newElement_0 =
            env->NewObject(threadMetricsStructStructClass_1, threadMetricsStructStructCtor_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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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
    {
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(value.Value(), javaValue));
    }

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

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

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

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

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

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

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

    jobject arrayListObj;
    chip::JniReferences::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);
}

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

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

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

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

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

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

    jobject arrayListObj;
    chip::JniReferences::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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::SecurityTypeEnum> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = 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::WiFiVersionEnum> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = 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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::PHYRateEnum> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = 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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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
    {
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(value.Value(), javaValue));
    }

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

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

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

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

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

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

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

    jobject arrayListObj;
    chip::JniReferences::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_offset;
        std::string newElement_0_offsetClassName     = "java/lang/Long";
        std::string newElement_0_offsetCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int32_t>(
            newElement_0_offsetClassName.c_str(), newElement_0_offsetCtorSignature.c_str(), entry_0.offset, newElement_0_offset);
        jobject newElement_0_validAt;
        std::string newElement_0_validAtClassName     = "java/lang/Long";
        std::string newElement_0_validAtCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_0_validAtClassName.c_str(),
                                                                       newElement_0_validAtCtorSignature.c_str(), entry_0.validAt,
                                                                       newElement_0_validAt);
        jobject newElement_0_name;
        if (!entry_0.name.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_name);
        }
        else
        {
            jobject newElement_0_nameInsideOptional;
            LogErrorOnFailure(
                chip::JniReferences::GetInstance().CharToStringUTF(entry_0.name.Value(), newElement_0_nameInsideOptional));
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_nameInsideOptional, newElement_0_name);
        }

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

        newElement_0 = env->NewObject(timeZoneStructStructClass_1, timeZoneStructStructCtor_1, newElement_0_offset,
                                      newElement_0_validAt, newElement_0_name);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

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

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

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

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

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

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

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

    jobject arrayListObj;
    chip::JniReferences::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_offset;
        std::string newElement_0_offsetClassName     = "java/lang/Long";
        std::string newElement_0_offsetCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int32_t>(
            newElement_0_offsetClassName.c_str(), newElement_0_offsetCtorSignature.c_str(), entry_0.offset, newElement_0_offset);
        jobject newElement_0_validStarting;
        std::string newElement_0_validStartingClassName     = "java/lang/Long";
        std::string newElement_0_validStartingCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_0_validStartingClassName.c_str(),
                                                                       newElement_0_validStartingCtorSignature.c_str(),
                                                                       entry_0.validStarting, newElement_0_validStarting);
        jobject newElement_0_validUntil;
        if (entry_0.validUntil.IsNull())
        {
            newElement_0_validUntil = nullptr;
        }
        else
        {
            std::string newElement_0_validUntilClassName     = "java/lang/Long";
            std::string newElement_0_validUntilCtorSignature = "(J)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_0_validUntilClassName.c_str(),
                                                                           newElement_0_validUntilCtorSignature.c_str(),
                                                                           entry_0.validUntil.Value(), newElement_0_validUntil);
        }

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

        newElement_0 = env->NewObject(DSTOffsetStructStructClass_1, DSTOffsetStructStructCtor_1, newElement_0_offset,
                                      newElement_0_validStarting, newElement_0_validUntil);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::FabricDescriptorStruct::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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.label, newElement_0_label));
        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 fabricDescriptorStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$OperationalCredentialsClusterFabricDescriptorStruct",
            fabricDescriptorStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$OperationalCredentialsClusterFabricDescriptorStruct");
            return;
        }
        jmethodID fabricDescriptorStructStructCtor_1 =
            env->GetMethodID(fabricDescriptorStructStructClass_1, "<init>",
                             "([BLjava/lang/Integer;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/String;Ljava/lang/Integer;)V");
        if (fabricDescriptorStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$OperationalCredentialsClusterFabricDescriptorStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(fabricDescriptorStructStructClass_1, fabricDescriptorStructStructCtor_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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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;
            LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.groupName.Value(),
                                                                                 newElement_0_groupNameInsideOptional));
            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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.label, newElement_0_label));
        jobject newElement_0_value;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.value, newElement_0_value));

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

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.label, newElement_0_label));
        jobject newElement_0_value;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.value, newElement_0_value));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

    jobject arrayListObj;
    chip::JniReferences::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_checkInNodeID;
        std::string newElement_0_checkInNodeIDClassName     = "java/lang/Long";
        std::string newElement_0_checkInNodeIDCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_0_checkInNodeIDClassName.c_str(),
                                                                       newElement_0_checkInNodeIDCtorSignature.c_str(),
                                                                       entry_0.checkInNodeID, newElement_0_checkInNodeID);
        jobject newElement_0_monitoredSubject;
        std::string newElement_0_monitoredSubjectClassName     = "java/lang/Long";
        std::string newElement_0_monitoredSubjectCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_0_monitoredSubjectClassName.c_str(),
                                                                       newElement_0_monitoredSubjectCtorSignature.c_str(),
                                                                       entry_0.monitoredSubject, newElement_0_monitoredSubject);
        jobject newElement_0_key;
        jbyteArray newElement_0_keyByteArray = env->NewByteArray(static_cast<jsize>(entry_0.key.size()));
        env->SetByteArrayRegion(newElement_0_keyByteArray, 0, static_cast<jsize>(entry_0.key.size()),
                                reinterpret_cast<const jbyte *>(entry_0.key.data()));
        newElement_0_key = newElement_0_keyByteArray;
        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 monitoringRegistrationStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$IcdManagementClusterMonitoringRegistrationStruct",
            monitoringRegistrationStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$IcdManagementClusterMonitoringRegistrationStruct");
            return;
        }
        jmethodID monitoringRegistrationStructStructCtor_1 = env->GetMethodID(
            monitoringRegistrationStructStructClass_1, "<init>", "(Ljava/lang/Long;Ljava/lang/Long;[BLjava/lang/Integer;)V");
        if (monitoringRegistrationStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$IcdManagementClusterMonitoringRegistrationStruct constructor");
            return;
        }

        newElement_0 =
            env->NewObject(monitoringRegistrationStructStructClass_1, monitoringRegistrationStructStructCtor_1,
                           newElement_0_checkInNodeID, newElement_0_monitoredSubject, newElement_0_key, newElement_0_fabricIndex);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.label, newElement_0_label));
        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(),
                static_cast<uint16_t>(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 semanticTagStructStructClass_3;
            err = chip::JniReferences::GetInstance().GetClassRef(
                env, "chip/devicecontroller/ChipStructs$ModeSelectClusterSemanticTagStruct", semanticTagStructStructClass_3);
            if (err != CHIP_NO_ERROR)
            {
                ChipLogError(Zcl, "Could not find class ChipStructs$ModeSelectClusterSemanticTagStruct");
                return;
            }
            jmethodID semanticTagStructStructCtor_3 =
                env->GetMethodID(semanticTagStructStructClass_3, "<init>", "(Ljava/lang/Integer;Ljava/lang/Integer;)V");
            if (semanticTagStructStructCtor_3 == nullptr)
            {
                ChipLogError(Zcl, "Could not find ChipStructs$ModeSelectClusterSemanticTagStruct constructor");
                return;
            }

            newElement_2 = env->NewObject(semanticTagStructStructClass_3, semanticTagStructStructCtor_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);
}

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

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

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

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

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

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

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

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

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

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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

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

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

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

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

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

    jobject arrayListObj;
    chip::JniReferences::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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.label, newElement_0_label));
        jobject newElement_0_temperatureLevel;
        std::string newElement_0_temperatureLevelClassName     = "java/lang/Integer";
        std::string newElement_0_temperatureLevelCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_temperatureLevelClassName.c_str(),
                                                                      newElement_0_temperatureLevelCtorSignature.c_str(),
                                                                      entry_0.temperatureLevel, newElement_0_temperatureLevel);

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

        newElement_0 = env->NewObject(temperatureLevelStructStructClass_1, temperatureLevelStructStructCtor_1, newElement_0_label,
                                      newElement_0_temperatureLevel);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTemperatureControlAttributeListAttributeCallback::CHIPTemperatureControlAttributeListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPTemperatureControlClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTemperatureControlAttributeListAttributeCallback::~CHIPTemperatureControlAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTemperatureControlAttributeListAttributeCallback::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<CHIPTemperatureControlAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTemperatureControlAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPRefrigeratorAlarmGeneratedCommandListAttributeCallback::CHIPRefrigeratorAlarmGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRefrigeratorAlarmClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRefrigeratorAlarmGeneratedCommandListAttributeCallback::~CHIPRefrigeratorAlarmGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRefrigeratorAlarmGeneratedCommandListAttributeCallback::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<CHIPRefrigeratorAlarmGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRefrigeratorAlarmGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPRefrigeratorAlarmAcceptedCommandListAttributeCallback::CHIPRefrigeratorAlarmAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRefrigeratorAlarmClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRefrigeratorAlarmAcceptedCommandListAttributeCallback::~CHIPRefrigeratorAlarmAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRefrigeratorAlarmAcceptedCommandListAttributeCallback::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<CHIPRefrigeratorAlarmAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRefrigeratorAlarmAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPRefrigeratorAlarmEventListAttributeCallback::CHIPRefrigeratorAlarmEventListAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPRefrigeratorAlarmClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRefrigeratorAlarmEventListAttributeCallback::~CHIPRefrigeratorAlarmEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRefrigeratorAlarmEventListAttributeCallback::CallbackFn(void * context,
                                                                 const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPRefrigeratorAlarmEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRefrigeratorAlarmEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPRefrigeratorAlarmAttributeListAttributeCallback::CHIPRefrigeratorAlarmAttributeListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPRefrigeratorAlarmClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRefrigeratorAlarmAttributeListAttributeCallback::~CHIPRefrigeratorAlarmAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRefrigeratorAlarmAttributeListAttributeCallback::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<CHIPRefrigeratorAlarmAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRefrigeratorAlarmAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAirQualityGeneratedCommandListAttributeCallback::CHIPAirQualityGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPAirQualityClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAirQualityGeneratedCommandListAttributeCallback::~CHIPAirQualityGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAirQualityGeneratedCommandListAttributeCallback::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<CHIPAirQualityGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAirQualityGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAirQualityAcceptedCommandListAttributeCallback::CHIPAirQualityAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPAirQualityClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAirQualityAcceptedCommandListAttributeCallback::~CHIPAirQualityAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAirQualityAcceptedCommandListAttributeCallback::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<CHIPAirQualityAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAirQualityAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAirQualityEventListAttributeCallback::CHIPAirQualityEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAirQualityClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAirQualityEventListAttributeCallback::~CHIPAirQualityEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAirQualityEventListAttributeCallback::CallbackFn(void * context,
                                                          const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAirQualityEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAirQualityEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPAirQualityAttributeListAttributeCallback::CHIPAirQualityAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAirQualityClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAirQualityAttributeListAttributeCallback::~CHIPAirQualityAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAirQualityAttributeListAttributeCallback::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<CHIPAirQualityAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAirQualityAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSmokeCoAlarmGeneratedCommandListAttributeCallback::CHIPSmokeCoAlarmGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPSmokeCoAlarmClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSmokeCoAlarmGeneratedCommandListAttributeCallback::~CHIPSmokeCoAlarmGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSmokeCoAlarmGeneratedCommandListAttributeCallback::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<CHIPSmokeCoAlarmGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSmokeCoAlarmGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSmokeCoAlarmAcceptedCommandListAttributeCallback::CHIPSmokeCoAlarmAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPSmokeCoAlarmClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSmokeCoAlarmAcceptedCommandListAttributeCallback::~CHIPSmokeCoAlarmAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSmokeCoAlarmAcceptedCommandListAttributeCallback::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<CHIPSmokeCoAlarmAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSmokeCoAlarmAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSmokeCoAlarmEventListAttributeCallback::CHIPSmokeCoAlarmEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSmokeCoAlarmClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSmokeCoAlarmEventListAttributeCallback::~CHIPSmokeCoAlarmEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSmokeCoAlarmEventListAttributeCallback::CallbackFn(void * context,
                                                            const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPSmokeCoAlarmEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSmokeCoAlarmEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSmokeCoAlarmAttributeListAttributeCallback::CHIPSmokeCoAlarmAttributeListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPSmokeCoAlarmClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSmokeCoAlarmAttributeListAttributeCallback::~CHIPSmokeCoAlarmAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSmokeCoAlarmAttributeListAttributeCallback::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<CHIPSmokeCoAlarmAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSmokeCoAlarmAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalStatePhaseListAttributeCallback::CHIPOperationalStatePhaseListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalStateClusterPhaseListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalStatePhaseListAttributeCallback::~CHIPOperationalStatePhaseListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalStatePhaseListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<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<CHIPOperationalStatePhaseListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalStatePhaseListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    if (list.IsNull())
    {
        arrayListObj = nullptr;
    }
    else
    {
        chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

        auto iter_arrayListObj_1 = list.Value().begin();
        while (iter_arrayListObj_1.Next())
        {
            auto & entry_1 = iter_arrayListObj_1.GetValue();
            jobject newElement_1;
            LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_1, newElement_1));
            chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_1);
        }
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalStateCurrentPhaseAttributeCallback::CHIPOperationalStateCurrentPhaseAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalStateClusterCurrentPhaseAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalStateCurrentPhaseAttributeCallback::~CHIPOperationalStateCurrentPhaseAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalStateCurrentPhaseAttributeCallback::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<CHIPOperationalStateCurrentPhaseAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalStateCurrentPhaseAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOperationalStateCountdownTimeAttributeCallback::CHIPOperationalStateCountdownTimeAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalStateClusterCountdownTimeAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalStateCountdownTimeAttributeCallback::~CHIPOperationalStateCountdownTimeAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalStateCountdownTimeAttributeCallback::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<CHIPOperationalStateCountdownTimeAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalStateCountdownTimeAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOperationalStateOperationalStateListAttributeCallback::CHIPOperationalStateOperationalStateListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalStateClusterOperationalStateListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalStateOperationalStateListAttributeCallback::~CHIPOperationalStateOperationalStateListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalStateOperationalStateListAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<
        chip::app::Clusters::OperationalState::Structs::OperationalStateStruct::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<CHIPOperationalStateOperationalStateListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalStateOperationalStateListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::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_operationalStateID;
        std::string newElement_0_operationalStateIDClassName     = "java/lang/Integer";
        std::string newElement_0_operationalStateIDCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_operationalStateIDClassName.c_str(), newElement_0_operationalStateIDCtorSignature.c_str(),
            static_cast<uint8_t>(entry_0.operationalStateID), newElement_0_operationalStateID);
        jobject newElement_0_operationalStateLabel;
        LogErrorOnFailure(
            chip::JniReferences::GetInstance().CharToStringUTF(entry_0.operationalStateLabel, newElement_0_operationalStateLabel));

        jclass operationalStateStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$OperationalStateClusterOperationalStateStruct",
            operationalStateStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$OperationalStateClusterOperationalStateStruct");
            return;
        }
        jmethodID operationalStateStructStructCtor_1 =
            env->GetMethodID(operationalStateStructStructClass_1, "<init>", "(Ljava/lang/Integer;Ljava/lang/String;)V");
        if (operationalStateStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$OperationalStateClusterOperationalStateStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(operationalStateStructStructClass_1, operationalStateStructStructCtor_1,
                                      newElement_0_operationalStateID, newElement_0_operationalStateLabel);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalStateGeneratedCommandListAttributeCallback::CHIPOperationalStateGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalStateClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalStateGeneratedCommandListAttributeCallback::~CHIPOperationalStateGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalStateGeneratedCommandListAttributeCallback::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<CHIPOperationalStateGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalStateGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalStateAcceptedCommandListAttributeCallback::CHIPOperationalStateAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalStateClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalStateAcceptedCommandListAttributeCallback::~CHIPOperationalStateAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalStateAcceptedCommandListAttributeCallback::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<CHIPOperationalStateAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalStateAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalStateEventListAttributeCallback::CHIPOperationalStateEventListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalStateClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalStateEventListAttributeCallback::~CHIPOperationalStateEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalStateEventListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOperationalStateEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalStateEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOperationalStateAttributeListAttributeCallback::CHIPOperationalStateAttributeListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPOperationalStateClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOperationalStateAttributeListAttributeCallback::~CHIPOperationalStateAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOperationalStateAttributeListAttributeCallback::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<CHIPOperationalStateAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOperationalStateAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHepaFilterMonitoringGeneratedCommandListAttributeCallback::CHIPHepaFilterMonitoringGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHepaFilterMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHepaFilterMonitoringGeneratedCommandListAttributeCallback::~CHIPHepaFilterMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHepaFilterMonitoringGeneratedCommandListAttributeCallback::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<CHIPHepaFilterMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHepaFilterMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHepaFilterMonitoringAcceptedCommandListAttributeCallback::CHIPHepaFilterMonitoringAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHepaFilterMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHepaFilterMonitoringAcceptedCommandListAttributeCallback::~CHIPHepaFilterMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHepaFilterMonitoringAcceptedCommandListAttributeCallback::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<CHIPHepaFilterMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHepaFilterMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHepaFilterMonitoringEventListAttributeCallback::CHIPHepaFilterMonitoringEventListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPHepaFilterMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHepaFilterMonitoringEventListAttributeCallback::~CHIPHepaFilterMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHepaFilterMonitoringEventListAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPHepaFilterMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHepaFilterMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHepaFilterMonitoringAttributeListAttributeCallback::CHIPHepaFilterMonitoringAttributeListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPHepaFilterMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHepaFilterMonitoringAttributeListAttributeCallback::~CHIPHepaFilterMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHepaFilterMonitoringAttributeListAttributeCallback::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<CHIPHepaFilterMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHepaFilterMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPActivatedCarbonFilterMonitoringGeneratedCommandListAttributeCallback::
    CHIPActivatedCarbonFilterMonitoringGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPActivatedCarbonFilterMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPActivatedCarbonFilterMonitoringGeneratedCommandListAttributeCallback::
    ~CHIPActivatedCarbonFilterMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPActivatedCarbonFilterMonitoringGeneratedCommandListAttributeCallback::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<CHIPActivatedCarbonFilterMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPActivatedCarbonFilterMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPActivatedCarbonFilterMonitoringAcceptedCommandListAttributeCallback::
    CHIPActivatedCarbonFilterMonitoringAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPActivatedCarbonFilterMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPActivatedCarbonFilterMonitoringAcceptedCommandListAttributeCallback::
    ~CHIPActivatedCarbonFilterMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPActivatedCarbonFilterMonitoringAcceptedCommandListAttributeCallback::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<CHIPActivatedCarbonFilterMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPActivatedCarbonFilterMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPActivatedCarbonFilterMonitoringEventListAttributeCallback::CHIPActivatedCarbonFilterMonitoringEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPActivatedCarbonFilterMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPActivatedCarbonFilterMonitoringEventListAttributeCallback::~CHIPActivatedCarbonFilterMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPActivatedCarbonFilterMonitoringEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPActivatedCarbonFilterMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPActivatedCarbonFilterMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPActivatedCarbonFilterMonitoringAttributeListAttributeCallback::
    CHIPActivatedCarbonFilterMonitoringAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPActivatedCarbonFilterMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPActivatedCarbonFilterMonitoringAttributeListAttributeCallback::
    ~CHIPActivatedCarbonFilterMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPActivatedCarbonFilterMonitoringAttributeListAttributeCallback::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<CHIPActivatedCarbonFilterMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPActivatedCarbonFilterMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCeramicFilterMonitoringGeneratedCommandListAttributeCallback::CHIPCeramicFilterMonitoringGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCeramicFilterMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCeramicFilterMonitoringGeneratedCommandListAttributeCallback::
    ~CHIPCeramicFilterMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCeramicFilterMonitoringGeneratedCommandListAttributeCallback::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<CHIPCeramicFilterMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCeramicFilterMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCeramicFilterMonitoringAcceptedCommandListAttributeCallback::CHIPCeramicFilterMonitoringAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCeramicFilterMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCeramicFilterMonitoringAcceptedCommandListAttributeCallback::~CHIPCeramicFilterMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCeramicFilterMonitoringAcceptedCommandListAttributeCallback::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<CHIPCeramicFilterMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCeramicFilterMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCeramicFilterMonitoringEventListAttributeCallback::CHIPCeramicFilterMonitoringEventListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPCeramicFilterMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCeramicFilterMonitoringEventListAttributeCallback::~CHIPCeramicFilterMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCeramicFilterMonitoringEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPCeramicFilterMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCeramicFilterMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCeramicFilterMonitoringAttributeListAttributeCallback::CHIPCeramicFilterMonitoringAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCeramicFilterMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCeramicFilterMonitoringAttributeListAttributeCallback::~CHIPCeramicFilterMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCeramicFilterMonitoringAttributeListAttributeCallback::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<CHIPCeramicFilterMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCeramicFilterMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPElectrostaticFilterMonitoringGeneratedCommandListAttributeCallback::
    CHIPElectrostaticFilterMonitoringGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPElectrostaticFilterMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPElectrostaticFilterMonitoringGeneratedCommandListAttributeCallback::
    ~CHIPElectrostaticFilterMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPElectrostaticFilterMonitoringGeneratedCommandListAttributeCallback::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<CHIPElectrostaticFilterMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPElectrostaticFilterMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPElectrostaticFilterMonitoringAcceptedCommandListAttributeCallback::
    CHIPElectrostaticFilterMonitoringAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPElectrostaticFilterMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPElectrostaticFilterMonitoringAcceptedCommandListAttributeCallback::
    ~CHIPElectrostaticFilterMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPElectrostaticFilterMonitoringAcceptedCommandListAttributeCallback::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<CHIPElectrostaticFilterMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPElectrostaticFilterMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPElectrostaticFilterMonitoringEventListAttributeCallback::CHIPElectrostaticFilterMonitoringEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPElectrostaticFilterMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPElectrostaticFilterMonitoringEventListAttributeCallback::~CHIPElectrostaticFilterMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPElectrostaticFilterMonitoringEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPElectrostaticFilterMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPElectrostaticFilterMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPElectrostaticFilterMonitoringAttributeListAttributeCallback::CHIPElectrostaticFilterMonitoringAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPElectrostaticFilterMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPElectrostaticFilterMonitoringAttributeListAttributeCallback::~CHIPElectrostaticFilterMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPElectrostaticFilterMonitoringAttributeListAttributeCallback::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<CHIPElectrostaticFilterMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPElectrostaticFilterMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPUvFilterMonitoringGeneratedCommandListAttributeCallback::CHIPUvFilterMonitoringGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUvFilterMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUvFilterMonitoringGeneratedCommandListAttributeCallback::~CHIPUvFilterMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUvFilterMonitoringGeneratedCommandListAttributeCallback::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<CHIPUvFilterMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUvFilterMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPUvFilterMonitoringAcceptedCommandListAttributeCallback::CHIPUvFilterMonitoringAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUvFilterMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUvFilterMonitoringAcceptedCommandListAttributeCallback::~CHIPUvFilterMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUvFilterMonitoringAcceptedCommandListAttributeCallback::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<CHIPUvFilterMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUvFilterMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPUvFilterMonitoringEventListAttributeCallback::CHIPUvFilterMonitoringEventListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPUvFilterMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUvFilterMonitoringEventListAttributeCallback::~CHIPUvFilterMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUvFilterMonitoringEventListAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPUvFilterMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUvFilterMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPUvFilterMonitoringAttributeListAttributeCallback::CHIPUvFilterMonitoringAttributeListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPUvFilterMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUvFilterMonitoringAttributeListAttributeCallback::~CHIPUvFilterMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUvFilterMonitoringAttributeListAttributeCallback::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<CHIPUvFilterMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUvFilterMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPIonizingFilterMonitoringGeneratedCommandListAttributeCallback::
    CHIPIonizingFilterMonitoringGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPIonizingFilterMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIonizingFilterMonitoringGeneratedCommandListAttributeCallback::
    ~CHIPIonizingFilterMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIonizingFilterMonitoringGeneratedCommandListAttributeCallback::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<CHIPIonizingFilterMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIonizingFilterMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPIonizingFilterMonitoringAcceptedCommandListAttributeCallback::CHIPIonizingFilterMonitoringAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPIonizingFilterMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIonizingFilterMonitoringAcceptedCommandListAttributeCallback::
    ~CHIPIonizingFilterMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIonizingFilterMonitoringAcceptedCommandListAttributeCallback::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<CHIPIonizingFilterMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIonizingFilterMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPIonizingFilterMonitoringEventListAttributeCallback::CHIPIonizingFilterMonitoringEventListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPIonizingFilterMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIonizingFilterMonitoringEventListAttributeCallback::~CHIPIonizingFilterMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIonizingFilterMonitoringEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPIonizingFilterMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIonizingFilterMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPIonizingFilterMonitoringAttributeListAttributeCallback::CHIPIonizingFilterMonitoringAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPIonizingFilterMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIonizingFilterMonitoringAttributeListAttributeCallback::~CHIPIonizingFilterMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIonizingFilterMonitoringAttributeListAttributeCallback::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<CHIPIonizingFilterMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIonizingFilterMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPZeoliteFilterMonitoringGeneratedCommandListAttributeCallback::CHIPZeoliteFilterMonitoringGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPZeoliteFilterMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPZeoliteFilterMonitoringGeneratedCommandListAttributeCallback::
    ~CHIPZeoliteFilterMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPZeoliteFilterMonitoringGeneratedCommandListAttributeCallback::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<CHIPZeoliteFilterMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPZeoliteFilterMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPZeoliteFilterMonitoringAcceptedCommandListAttributeCallback::CHIPZeoliteFilterMonitoringAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPZeoliteFilterMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPZeoliteFilterMonitoringAcceptedCommandListAttributeCallback::~CHIPZeoliteFilterMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPZeoliteFilterMonitoringAcceptedCommandListAttributeCallback::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<CHIPZeoliteFilterMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPZeoliteFilterMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPZeoliteFilterMonitoringEventListAttributeCallback::CHIPZeoliteFilterMonitoringEventListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPZeoliteFilterMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPZeoliteFilterMonitoringEventListAttributeCallback::~CHIPZeoliteFilterMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPZeoliteFilterMonitoringEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPZeoliteFilterMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPZeoliteFilterMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPZeoliteFilterMonitoringAttributeListAttributeCallback::CHIPZeoliteFilterMonitoringAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPZeoliteFilterMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPZeoliteFilterMonitoringAttributeListAttributeCallback::~CHIPZeoliteFilterMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPZeoliteFilterMonitoringAttributeListAttributeCallback::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<CHIPZeoliteFilterMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPZeoliteFilterMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOzoneFilterMonitoringGeneratedCommandListAttributeCallback::CHIPOzoneFilterMonitoringGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneFilterMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneFilterMonitoringGeneratedCommandListAttributeCallback::~CHIPOzoneFilterMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneFilterMonitoringGeneratedCommandListAttributeCallback::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<CHIPOzoneFilterMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneFilterMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOzoneFilterMonitoringAcceptedCommandListAttributeCallback::CHIPOzoneFilterMonitoringAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneFilterMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneFilterMonitoringAcceptedCommandListAttributeCallback::~CHIPOzoneFilterMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneFilterMonitoringAcceptedCommandListAttributeCallback::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<CHIPOzoneFilterMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneFilterMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOzoneFilterMonitoringEventListAttributeCallback::CHIPOzoneFilterMonitoringEventListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneFilterMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneFilterMonitoringEventListAttributeCallback::~CHIPOzoneFilterMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneFilterMonitoringEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOzoneFilterMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneFilterMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOzoneFilterMonitoringAttributeListAttributeCallback::CHIPOzoneFilterMonitoringAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneFilterMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneFilterMonitoringAttributeListAttributeCallback::~CHIPOzoneFilterMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneFilterMonitoringAttributeListAttributeCallback::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<CHIPOzoneFilterMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneFilterMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWaterTankMonitoringGeneratedCommandListAttributeCallback::CHIPWaterTankMonitoringGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWaterTankMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWaterTankMonitoringGeneratedCommandListAttributeCallback::~CHIPWaterTankMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWaterTankMonitoringGeneratedCommandListAttributeCallback::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<CHIPWaterTankMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWaterTankMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWaterTankMonitoringAcceptedCommandListAttributeCallback::CHIPWaterTankMonitoringAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWaterTankMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWaterTankMonitoringAcceptedCommandListAttributeCallback::~CHIPWaterTankMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWaterTankMonitoringAcceptedCommandListAttributeCallback::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<CHIPWaterTankMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWaterTankMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWaterTankMonitoringEventListAttributeCallback::CHIPWaterTankMonitoringEventListAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPWaterTankMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWaterTankMonitoringEventListAttributeCallback::~CHIPWaterTankMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWaterTankMonitoringEventListAttributeCallback::CallbackFn(void * context,
                                                                   const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWaterTankMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWaterTankMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPWaterTankMonitoringAttributeListAttributeCallback::CHIPWaterTankMonitoringAttributeListAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPWaterTankMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWaterTankMonitoringAttributeListAttributeCallback::~CHIPWaterTankMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWaterTankMonitoringAttributeListAttributeCallback::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<CHIPWaterTankMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWaterTankMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFuelTankMonitoringGeneratedCommandListAttributeCallback::CHIPFuelTankMonitoringGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFuelTankMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFuelTankMonitoringGeneratedCommandListAttributeCallback::~CHIPFuelTankMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFuelTankMonitoringGeneratedCommandListAttributeCallback::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<CHIPFuelTankMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFuelTankMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFuelTankMonitoringAcceptedCommandListAttributeCallback::CHIPFuelTankMonitoringAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFuelTankMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFuelTankMonitoringAcceptedCommandListAttributeCallback::~CHIPFuelTankMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFuelTankMonitoringAcceptedCommandListAttributeCallback::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<CHIPFuelTankMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFuelTankMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFuelTankMonitoringEventListAttributeCallback::CHIPFuelTankMonitoringEventListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPFuelTankMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFuelTankMonitoringEventListAttributeCallback::~CHIPFuelTankMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFuelTankMonitoringEventListAttributeCallback::CallbackFn(void * context,
                                                                  const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFuelTankMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFuelTankMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFuelTankMonitoringAttributeListAttributeCallback::CHIPFuelTankMonitoringAttributeListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPFuelTankMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFuelTankMonitoringAttributeListAttributeCallback::~CHIPFuelTankMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFuelTankMonitoringAttributeListAttributeCallback::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<CHIPFuelTankMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFuelTankMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPInkCartridgeMonitoringGeneratedCommandListAttributeCallback::CHIPInkCartridgeMonitoringGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPInkCartridgeMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInkCartridgeMonitoringGeneratedCommandListAttributeCallback::~CHIPInkCartridgeMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInkCartridgeMonitoringGeneratedCommandListAttributeCallback::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<CHIPInkCartridgeMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInkCartridgeMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPInkCartridgeMonitoringAcceptedCommandListAttributeCallback::CHIPInkCartridgeMonitoringAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPInkCartridgeMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInkCartridgeMonitoringAcceptedCommandListAttributeCallback::~CHIPInkCartridgeMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInkCartridgeMonitoringAcceptedCommandListAttributeCallback::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<CHIPInkCartridgeMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInkCartridgeMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPInkCartridgeMonitoringEventListAttributeCallback::CHIPInkCartridgeMonitoringEventListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPInkCartridgeMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInkCartridgeMonitoringEventListAttributeCallback::~CHIPInkCartridgeMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInkCartridgeMonitoringEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPInkCartridgeMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInkCartridgeMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPInkCartridgeMonitoringAttributeListAttributeCallback::CHIPInkCartridgeMonitoringAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPInkCartridgeMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPInkCartridgeMonitoringAttributeListAttributeCallback::~CHIPInkCartridgeMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPInkCartridgeMonitoringAttributeListAttributeCallback::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<CHIPInkCartridgeMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPInkCartridgeMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTonerCartridgeMonitoringGeneratedCommandListAttributeCallback::
    CHIPTonerCartridgeMonitoringGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTonerCartridgeMonitoringClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTonerCartridgeMonitoringGeneratedCommandListAttributeCallback::
    ~CHIPTonerCartridgeMonitoringGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTonerCartridgeMonitoringGeneratedCommandListAttributeCallback::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<CHIPTonerCartridgeMonitoringGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTonerCartridgeMonitoringGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTonerCartridgeMonitoringAcceptedCommandListAttributeCallback::CHIPTonerCartridgeMonitoringAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTonerCartridgeMonitoringClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTonerCartridgeMonitoringAcceptedCommandListAttributeCallback::
    ~CHIPTonerCartridgeMonitoringAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTonerCartridgeMonitoringAcceptedCommandListAttributeCallback::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<CHIPTonerCartridgeMonitoringAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTonerCartridgeMonitoringAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTonerCartridgeMonitoringEventListAttributeCallback::CHIPTonerCartridgeMonitoringEventListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTonerCartridgeMonitoringClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTonerCartridgeMonitoringEventListAttributeCallback::~CHIPTonerCartridgeMonitoringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTonerCartridgeMonitoringEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTonerCartridgeMonitoringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTonerCartridgeMonitoringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTonerCartridgeMonitoringAttributeListAttributeCallback::CHIPTonerCartridgeMonitoringAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTonerCartridgeMonitoringClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTonerCartridgeMonitoringAttributeListAttributeCallback::~CHIPTonerCartridgeMonitoringAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTonerCartridgeMonitoringAttributeListAttributeCallback::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<CHIPTonerCartridgeMonitoringAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTonerCartridgeMonitoringAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::DoorStateEnum> & value)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = 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);
}

CHIPDoorLockEventListAttributeCallback::CHIPDoorLockEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDoorLockClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDoorLockEventListAttributeCallback::~CHIPDoorLockEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDoorLockEventListAttributeCallback::CallbackFn(void * context,
                                                        const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDoorLockEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDoorLockEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPWindowCoveringEventListAttributeCallback::CHIPWindowCoveringEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWindowCoveringClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWindowCoveringEventListAttributeCallback::~CHIPWindowCoveringEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWindowCoveringEventListAttributeCallback::CallbackFn(void * context,
                                                              const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWindowCoveringEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWindowCoveringEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPBarrierControlEventListAttributeCallback::CHIPBarrierControlEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBarrierControlClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBarrierControlEventListAttributeCallback::~CHIPBarrierControlEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBarrierControlEventListAttributeCallback::CallbackFn(void * context,
                                                              const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBarrierControlEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBarrierControlEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPPumpConfigurationAndControlEventListAttributeCallback::CHIPPumpConfigurationAndControlEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPumpConfigurationAndControlClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPumpConfigurationAndControlEventListAttributeCallback::~CHIPPumpConfigurationAndControlEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPumpConfigurationAndControlEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPumpConfigurationAndControlEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPumpConfigurationAndControlEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPThermostatOutdoorTemperatureAttributeCallback::CHIPThermostatOutdoorTemperatureAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterOutdoorTemperatureAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatOutdoorTemperatureAttributeCallback::~CHIPThermostatOutdoorTemperatureAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatOutdoorTemperatureAttributeCallback::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<CHIPThermostatOutdoorTemperatureAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatOutdoorTemperatureAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPThermostatTemperatureSetpointHoldDurationAttributeCallback::CHIPThermostatTemperatureSetpointHoldDurationAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterTemperatureSetpointHoldDurationAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatTemperatureSetpointHoldDurationAttributeCallback::~CHIPThermostatTemperatureSetpointHoldDurationAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatTemperatureSetpointHoldDurationAttributeCallback::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<CHIPThermostatTemperatureSetpointHoldDurationAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatTemperatureSetpointHoldDurationAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPThermostatSetpointChangeAmountAttributeCallback::CHIPThermostatSetpointChangeAmountAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterSetpointChangeAmountAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatSetpointChangeAmountAttributeCallback::~CHIPThermostatSetpointChangeAmountAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatSetpointChangeAmountAttributeCallback::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<CHIPThermostatSetpointChangeAmountAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatSetpointChangeAmountAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPThermostatOccupiedSetbackAttributeCallback::CHIPThermostatOccupiedSetbackAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterOccupiedSetbackAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatOccupiedSetbackAttributeCallback::~CHIPThermostatOccupiedSetbackAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatOccupiedSetbackAttributeCallback::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<CHIPThermostatOccupiedSetbackAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatOccupiedSetbackAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPThermostatOccupiedSetbackMinAttributeCallback::CHIPThermostatOccupiedSetbackMinAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterOccupiedSetbackMinAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatOccupiedSetbackMinAttributeCallback::~CHIPThermostatOccupiedSetbackMinAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatOccupiedSetbackMinAttributeCallback::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<CHIPThermostatOccupiedSetbackMinAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatOccupiedSetbackMinAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPThermostatOccupiedSetbackMaxAttributeCallback::CHIPThermostatOccupiedSetbackMaxAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterOccupiedSetbackMaxAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatOccupiedSetbackMaxAttributeCallback::~CHIPThermostatOccupiedSetbackMaxAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatOccupiedSetbackMaxAttributeCallback::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<CHIPThermostatOccupiedSetbackMaxAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatOccupiedSetbackMaxAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPThermostatUnoccupiedSetbackAttributeCallback::CHIPThermostatUnoccupiedSetbackAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterUnoccupiedSetbackAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatUnoccupiedSetbackAttributeCallback::~CHIPThermostatUnoccupiedSetbackAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatUnoccupiedSetbackAttributeCallback::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<CHIPThermostatUnoccupiedSetbackAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatUnoccupiedSetbackAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPThermostatUnoccupiedSetbackMinAttributeCallback::CHIPThermostatUnoccupiedSetbackMinAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterUnoccupiedSetbackMinAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatUnoccupiedSetbackMinAttributeCallback::~CHIPThermostatUnoccupiedSetbackMinAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatUnoccupiedSetbackMinAttributeCallback::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<CHIPThermostatUnoccupiedSetbackMinAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatUnoccupiedSetbackMinAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPThermostatUnoccupiedSetbackMaxAttributeCallback::CHIPThermostatUnoccupiedSetbackMaxAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterUnoccupiedSetbackMaxAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatUnoccupiedSetbackMaxAttributeCallback::~CHIPThermostatUnoccupiedSetbackMaxAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatUnoccupiedSetbackMaxAttributeCallback::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<CHIPThermostatUnoccupiedSetbackMaxAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatUnoccupiedSetbackMaxAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPThermostatACCoilTemperatureAttributeCallback::CHIPThermostatACCoilTemperatureAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterACCoilTemperatureAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatACCoilTemperatureAttributeCallback::~CHIPThermostatACCoilTemperatureAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatACCoilTemperatureAttributeCallback::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<CHIPThermostatACCoilTemperatureAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatACCoilTemperatureAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPThermostatGeneratedCommandListAttributeCallback::CHIPThermostatGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatGeneratedCommandListAttributeCallback::~CHIPThermostatGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatGeneratedCommandListAttributeCallback::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<CHIPThermostatGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThermostatAcceptedCommandListAttributeCallback::CHIPThermostatAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatAcceptedCommandListAttributeCallback::~CHIPThermostatAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatAcceptedCommandListAttributeCallback::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<CHIPThermostatAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPThermostatEventListAttributeCallback::CHIPThermostatEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatEventListAttributeCallback::~CHIPThermostatEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatEventListAttributeCallback::CallbackFn(void * context,
                                                          const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThermostatEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

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);
}

CHIPFanControlEventListAttributeCallback::CHIPFanControlEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFanControlClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFanControlEventListAttributeCallback::~CHIPFanControlEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFanControlEventListAttributeCallback::CallbackFn(void * context,
                                                          const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFanControlEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFanControlEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPThermostatUserInterfaceConfigurationEventListAttributeCallback::
    CHIPThermostatUserInterfaceConfigurationEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPThermostatUserInterfaceConfigurationClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPThermostatUserInterfaceConfigurationEventListAttributeCallback::
    ~CHIPThermostatUserInterfaceConfigurationEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPThermostatUserInterfaceConfigurationEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPThermostatUserInterfaceConfigurationEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPThermostatUserInterfaceConfigurationEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPColorControlStartUpColorTemperatureMiredsAttributeCallback::CHIPColorControlStartUpColorTemperatureMiredsAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterStartUpColorTemperatureMiredsAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlStartUpColorTemperatureMiredsAttributeCallback::~CHIPColorControlStartUpColorTemperatureMiredsAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlStartUpColorTemperatureMiredsAttributeCallback::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<CHIPColorControlStartUpColorTemperatureMiredsAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlStartUpColorTemperatureMiredsAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

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);
}

CHIPColorControlEventListAttributeCallback::CHIPColorControlEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPColorControlClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPColorControlEventListAttributeCallback::~CHIPColorControlEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPColorControlEventListAttributeCallback::CallbackFn(void * context,
                                                            const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPColorControlEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPColorControlEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPBallastConfigurationIntrinsicBallastFactorAttributeCallback::CHIPBallastConfigurationIntrinsicBallastFactorAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBallastConfigurationClusterIntrinsicBallastFactorAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBallastConfigurationIntrinsicBallastFactorAttributeCallback::~CHIPBallastConfigurationIntrinsicBallastFactorAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBallastConfigurationIntrinsicBallastFactorAttributeCallback::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<CHIPBallastConfigurationIntrinsicBallastFactorAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBallastConfigurationIntrinsicBallastFactorAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBallastConfigurationEventListAttributeCallback::CHIPBallastConfigurationEventListAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPBallastConfigurationClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBallastConfigurationEventListAttributeCallback::~CHIPBallastConfigurationEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBallastConfigurationEventListAttributeCallback::CallbackFn(void * context,
                                                                    const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBallastConfigurationEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBallastConfigurationEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPIlluminanceMeasurementEventListAttributeCallback::CHIPIlluminanceMeasurementEventListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPIlluminanceMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPIlluminanceMeasurementEventListAttributeCallback::~CHIPIlluminanceMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPIlluminanceMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPIlluminanceMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPIlluminanceMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPTemperatureMeasurementGeneratedCommandListAttributeCallback::CHIPTemperatureMeasurementGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTemperatureMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTemperatureMeasurementGeneratedCommandListAttributeCallback::~CHIPTemperatureMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTemperatureMeasurementGeneratedCommandListAttributeCallback::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<CHIPTemperatureMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTemperatureMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTemperatureMeasurementAcceptedCommandListAttributeCallback::CHIPTemperatureMeasurementAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTemperatureMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTemperatureMeasurementAcceptedCommandListAttributeCallback::~CHIPTemperatureMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTemperatureMeasurementAcceptedCommandListAttributeCallback::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<CHIPTemperatureMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTemperatureMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTemperatureMeasurementEventListAttributeCallback::CHIPTemperatureMeasurementEventListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPTemperatureMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTemperatureMeasurementEventListAttributeCallback::~CHIPTemperatureMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTemperatureMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTemperatureMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTemperatureMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

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);
}

CHIPPressureMeasurementGeneratedCommandListAttributeCallback::CHIPPressureMeasurementGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPressureMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPressureMeasurementGeneratedCommandListAttributeCallback::~CHIPPressureMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPressureMeasurementGeneratedCommandListAttributeCallback::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<CHIPPressureMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPressureMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPressureMeasurementAcceptedCommandListAttributeCallback::CHIPPressureMeasurementAcceptedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPressureMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPressureMeasurementAcceptedCommandListAttributeCallback::~CHIPPressureMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPressureMeasurementAcceptedCommandListAttributeCallback::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<CHIPPressureMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPressureMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPressureMeasurementEventListAttributeCallback::CHIPPressureMeasurementEventListAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPPressureMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPressureMeasurementEventListAttributeCallback::~CHIPPressureMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPressureMeasurementEventListAttributeCallback::CallbackFn(void * context,
                                                                   const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPressureMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPressureMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

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);
}

CHIPFlowMeasurementEventListAttributeCallback::CHIPFlowMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFlowMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFlowMeasurementEventListAttributeCallback::~CHIPFlowMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFlowMeasurementEventListAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFlowMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFlowMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPRelativeHumidityMeasurementEventListAttributeCallback::CHIPRelativeHumidityMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRelativeHumidityMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRelativeHumidityMeasurementEventListAttributeCallback::~CHIPRelativeHumidityMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRelativeHumidityMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPRelativeHumidityMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRelativeHumidityMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPOccupancySensingEventListAttributeCallback::CHIPOccupancySensingEventListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPOccupancySensingClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOccupancySensingEventListAttributeCallback::~CHIPOccupancySensingEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOccupancySensingEventListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOccupancySensingEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOccupancySensingEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPCarbonMonoxideConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPCarbonMonoxideConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonMonoxideConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonMonoxideConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPCarbonMonoxideConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonMonoxideConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPCarbonMonoxideConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCarbonMonoxideConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCarbonMonoxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPCarbonMonoxideConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonMonoxideConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                     this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonMonoxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPCarbonMonoxideConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonMonoxideConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPCarbonMonoxideConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonMonoxideConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCarbonMonoxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPCarbonMonoxideConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonMonoxideConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                     this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonMonoxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPCarbonMonoxideConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonMonoxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPCarbonMonoxideConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonMonoxideConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCarbonMonoxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPCarbonMonoxideConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonMonoxideConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonMonoxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPCarbonMonoxideConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonMonoxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPCarbonMonoxideConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonMonoxideConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCarbonMonoxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPCarbonMonoxideConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonMonoxideConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                         this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonMonoxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPCarbonMonoxideConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonMonoxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPCarbonMonoxideConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonMonoxideConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCarbonMonoxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPCarbonMonoxideConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonMonoxideConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                         this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonMonoxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPCarbonMonoxideConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonMonoxideConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPCarbonMonoxideConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonMonoxideConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCarbonMonoxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPCarbonMonoxideConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonMonoxideConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonMonoxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPCarbonMonoxideConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonMonoxideConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPCarbonMonoxideConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonMonoxideConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCarbonMonoxideConcentrationMeasurementEventListAttributeCallback::
    CHIPCarbonMonoxideConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonMonoxideConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonMonoxideConcentrationMeasurementEventListAttributeCallback::
    ~CHIPCarbonMonoxideConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonMonoxideConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPCarbonMonoxideConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCarbonMonoxideConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCarbonMonoxideConcentrationMeasurementAttributeListAttributeCallback::
    CHIPCarbonMonoxideConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonMonoxideConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonMonoxideConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPCarbonMonoxideConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonMonoxideConcentrationMeasurementAttributeListAttributeCallback::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<CHIPCarbonMonoxideConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCarbonMonoxideConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCarbonDioxideConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPCarbonDioxideConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonDioxideConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonDioxideConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPCarbonDioxideConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonDioxideConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPCarbonDioxideConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCarbonDioxideConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCarbonDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPCarbonDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonDioxideConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPCarbonDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPCarbonDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCarbonDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPCarbonDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonDioxideConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPCarbonDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPCarbonDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCarbonDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPCarbonDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonDioxideConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                     this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPCarbonDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPCarbonDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCarbonDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPCarbonDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonDioxideConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPCarbonDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPCarbonDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCarbonDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPCarbonDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonDioxideConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPCarbonDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPCarbonDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCarbonDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPCarbonDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonDioxideConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                       this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPCarbonDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPCarbonDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPCarbonDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCarbonDioxideConcentrationMeasurementEventListAttributeCallback::
    CHIPCarbonDioxideConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonDioxideConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonDioxideConcentrationMeasurementEventListAttributeCallback::
    ~CHIPCarbonDioxideConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonDioxideConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPCarbonDioxideConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCarbonDioxideConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCarbonDioxideConcentrationMeasurementAttributeListAttributeCallback::
    CHIPCarbonDioxideConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCarbonDioxideConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCarbonDioxideConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPCarbonDioxideConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCarbonDioxideConcentrationMeasurementAttributeListAttributeCallback::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<CHIPCarbonDioxideConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCarbonDioxideConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPEthyleneConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPEthyleneConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPEthyleneConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPEthyleneConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPEthyleneConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPEthyleneConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPEthyleneConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPEthyleneConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPEthyleneConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPEthyleneConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPEthyleneConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPEthyleneConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPEthyleneConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPEthyleneConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPEthyleneConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPEthyleneConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPEthyleneConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPEthyleneConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPEthyleneConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPEthyleneConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPEthyleneConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPEthyleneConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPEthyleneConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPEthyleneConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPEthyleneConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPEthyleneConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPEthyleneConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPEthyleneConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPEthyleneConcentrationMeasurementEventListAttributeCallback::CHIPEthyleneConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneConcentrationMeasurementEventListAttributeCallback::~CHIPEthyleneConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPEthyleneConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPEthyleneConcentrationMeasurementAttributeListAttributeCallback::
    CHIPEthyleneConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPEthyleneConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneConcentrationMeasurementAttributeListAttributeCallback::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<CHIPEthyleneConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPEthyleneOxideConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPEthyleneOxideConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneOxideConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneOxideConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPEthyleneOxideConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneOxideConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPEthyleneOxideConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneOxideConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPEthyleneOxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPEthyleneOxideConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneOxideConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneOxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPEthyleneOxideConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneOxideConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPEthyleneOxideConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPEthyleneOxideConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPEthyleneOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPEthyleneOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneOxideConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPEthyleneOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPEthyleneOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPEthyleneOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPEthyleneOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPEthyleneOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneOxideConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                     this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPEthyleneOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPEthyleneOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPEthyleneOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPEthyleneOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPEthyleneOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneOxideConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPEthyleneOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPEthyleneOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPEthyleneOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPEthyleneOxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPEthyleneOxideConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneOxideConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneOxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPEthyleneOxideConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneOxideConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPEthyleneOxideConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPEthyleneOxideConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPEthyleneOxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPEthyleneOxideConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneOxideConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                       this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneOxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPEthyleneOxideConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneOxideConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPEthyleneOxideConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPEthyleneOxideConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPEthyleneOxideConcentrationMeasurementEventListAttributeCallback::
    CHIPEthyleneOxideConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneOxideConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneOxideConcentrationMeasurementEventListAttributeCallback::
    ~CHIPEthyleneOxideConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneOxideConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPEthyleneOxideConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneOxideConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPEthyleneOxideConcentrationMeasurementAttributeListAttributeCallback::
    CHIPEthyleneOxideConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPEthyleneOxideConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPEthyleneOxideConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPEthyleneOxideConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPEthyleneOxideConcentrationMeasurementAttributeListAttributeCallback::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<CHIPEthyleneOxideConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPEthyleneOxideConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHydrogenConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPHydrogenConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPHydrogenConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPHydrogenConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHydrogenConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPHydrogenConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPHydrogenConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPHydrogenConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHydrogenConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPHydrogenConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPHydrogenConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPHydrogenConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHydrogenConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPHydrogenConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPHydrogenConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPHydrogenConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHydrogenConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPHydrogenConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPHydrogenConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPHydrogenConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHydrogenConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPHydrogenConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPHydrogenConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPHydrogenConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHydrogenConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPHydrogenConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPHydrogenConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPHydrogenConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHydrogenConcentrationMeasurementEventListAttributeCallback::CHIPHydrogenConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenConcentrationMeasurementEventListAttributeCallback::~CHIPHydrogenConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPHydrogenConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHydrogenConcentrationMeasurementAttributeListAttributeCallback::
    CHIPHydrogenConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPHydrogenConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenConcentrationMeasurementAttributeListAttributeCallback::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<CHIPHydrogenConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHydrogenSulfideConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPHydrogenSulfideConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenSulfideConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenSulfideConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPHydrogenSulfideConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenSulfideConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPHydrogenSulfideConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenSulfideConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHydrogenSulfideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPHydrogenSulfideConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenSulfideConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenSulfideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPHydrogenSulfideConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenSulfideConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPHydrogenSulfideConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHydrogenSulfideConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHydrogenSulfideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPHydrogenSulfideConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenSulfideConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenSulfideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPHydrogenSulfideConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenSulfideConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPHydrogenSulfideConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHydrogenSulfideConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHydrogenSulfideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPHydrogenSulfideConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenSulfideConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                       this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenSulfideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPHydrogenSulfideConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenSulfideConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPHydrogenSulfideConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHydrogenSulfideConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHydrogenSulfideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPHydrogenSulfideConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenSulfideConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenSulfideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPHydrogenSulfideConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenSulfideConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPHydrogenSulfideConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHydrogenSulfideConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHydrogenSulfideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPHydrogenSulfideConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenSulfideConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenSulfideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPHydrogenSulfideConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenSulfideConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPHydrogenSulfideConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHydrogenSulfideConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHydrogenSulfideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPHydrogenSulfideConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenSulfideConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                         this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenSulfideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPHydrogenSulfideConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenSulfideConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPHydrogenSulfideConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHydrogenSulfideConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHydrogenSulfideConcentrationMeasurementEventListAttributeCallback::
    CHIPHydrogenSulfideConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenSulfideConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenSulfideConcentrationMeasurementEventListAttributeCallback::
    ~CHIPHydrogenSulfideConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenSulfideConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPHydrogenSulfideConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenSulfideConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHydrogenSulfideConcentrationMeasurementAttributeListAttributeCallback::
    CHIPHydrogenSulfideConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHydrogenSulfideConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHydrogenSulfideConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPHydrogenSulfideConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHydrogenSulfideConcentrationMeasurementAttributeListAttributeCallback::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<CHIPHydrogenSulfideConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHydrogenSulfideConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPNitricOxideConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPNitricOxideConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitricOxideConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitricOxideConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPNitricOxideConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitricOxideConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPNitricOxideConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNitricOxideConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPNitricOxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPNitricOxideConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitricOxideConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitricOxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPNitricOxideConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitricOxideConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPNitricOxideConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNitricOxideConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPNitricOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPNitricOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitricOxideConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitricOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPNitricOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitricOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPNitricOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNitricOxideConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPNitricOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPNitricOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitricOxideConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitricOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPNitricOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitricOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPNitricOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNitricOxideConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPNitricOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPNitricOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitricOxideConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitricOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPNitricOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitricOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPNitricOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPNitricOxideConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPNitricOxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPNitricOxideConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitricOxideConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitricOxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPNitricOxideConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitricOxideConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPNitricOxideConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPNitricOxideConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPNitricOxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPNitricOxideConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitricOxideConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                     this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitricOxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPNitricOxideConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitricOxideConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPNitricOxideConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPNitricOxideConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPNitricOxideConcentrationMeasurementEventListAttributeCallback::
    CHIPNitricOxideConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitricOxideConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitricOxideConcentrationMeasurementEventListAttributeCallback::
    ~CHIPNitricOxideConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitricOxideConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPNitricOxideConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNitricOxideConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPNitricOxideConcentrationMeasurementAttributeListAttributeCallback::
    CHIPNitricOxideConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitricOxideConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitricOxideConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPNitricOxideConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitricOxideConcentrationMeasurementAttributeListAttributeCallback::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<CHIPNitricOxideConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNitricOxideConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPNitrogenDioxideConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPNitrogenDioxideConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitrogenDioxideConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitrogenDioxideConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPNitrogenDioxideConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitrogenDioxideConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPNitrogenDioxideConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNitrogenDioxideConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPNitrogenDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPNitrogenDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitrogenDioxideConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitrogenDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPNitrogenDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitrogenDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPNitrogenDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPNitrogenDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPNitrogenDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPNitrogenDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitrogenDioxideConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitrogenDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPNitrogenDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitrogenDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPNitrogenDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPNitrogenDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPNitrogenDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPNitrogenDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitrogenDioxideConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                       this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitrogenDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPNitrogenDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitrogenDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPNitrogenDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPNitrogenDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPNitrogenDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPNitrogenDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitrogenDioxideConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitrogenDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPNitrogenDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitrogenDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPNitrogenDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPNitrogenDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPNitrogenDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPNitrogenDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitrogenDioxideConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitrogenDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPNitrogenDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitrogenDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPNitrogenDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPNitrogenDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPNitrogenDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPNitrogenDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitrogenDioxideConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                         this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitrogenDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPNitrogenDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitrogenDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPNitrogenDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPNitrogenDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPNitrogenDioxideConcentrationMeasurementEventListAttributeCallback::
    CHIPNitrogenDioxideConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitrogenDioxideConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitrogenDioxideConcentrationMeasurementEventListAttributeCallback::
    ~CHIPNitrogenDioxideConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitrogenDioxideConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPNitrogenDioxideConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNitrogenDioxideConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPNitrogenDioxideConcentrationMeasurementAttributeListAttributeCallback::
    CHIPNitrogenDioxideConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPNitrogenDioxideConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPNitrogenDioxideConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPNitrogenDioxideConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPNitrogenDioxideConcentrationMeasurementAttributeListAttributeCallback::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<CHIPNitrogenDioxideConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPNitrogenDioxideConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOxygenConcentrationMeasurementMeasuredValueAttributeCallback::CHIPOxygenConcentrationMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOxygenConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOxygenConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPOxygenConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOxygenConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPOxygenConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOxygenConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOxygenConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOxygenConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOxygenConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOxygenConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOxygenConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOxygenConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOxygenConcentrationMeasurementEventListAttributeCallback::CHIPOxygenConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOxygenConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOxygenConcentrationMeasurementEventListAttributeCallback::~CHIPOxygenConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOxygenConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOxygenConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOxygenConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOxygenConcentrationMeasurementAttributeListAttributeCallback::CHIPOxygenConcentrationMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOxygenConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOxygenConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPOxygenConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOxygenConcentrationMeasurementAttributeListAttributeCallback::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<CHIPOxygenConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOxygenConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOzoneConcentrationMeasurementMeasuredValueAttributeCallback::CHIPOzoneConcentrationMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneConcentrationMeasurementMeasuredValueAttributeCallback::~CHIPOzoneConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPOzoneConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOzoneConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPOzoneConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPOzoneConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPOzoneConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOzoneConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPOzoneConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPOzoneConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPOzoneConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOzoneConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPOzoneConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPOzoneConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPOzoneConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOzoneConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPOzoneConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPOzoneConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPOzoneConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPOzoneConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPOzoneConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPOzoneConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPOzoneConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOzoneConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPOzoneConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPOzoneConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPOzoneConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOzoneConcentrationMeasurementEventListAttributeCallback::CHIPOzoneConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneConcentrationMeasurementEventListAttributeCallback::~CHIPOzoneConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPOzoneConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPOzoneConcentrationMeasurementAttributeListAttributeCallback::CHIPOzoneConcentrationMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPOzoneConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPOzoneConcentrationMeasurementAttributeListAttributeCallback::~CHIPOzoneConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPOzoneConcentrationMeasurementAttributeListAttributeCallback::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<CHIPOzoneConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPOzoneConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSulfurDioxideConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPSulfurDioxideConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfurDioxideConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfurDioxideConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPSulfurDioxideConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfurDioxideConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPSulfurDioxideConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfurDioxideConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSulfurDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPSulfurDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfurDioxideConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfurDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPSulfurDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfurDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPSulfurDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPSulfurDioxideConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSulfurDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPSulfurDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfurDioxideConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfurDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPSulfurDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfurDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPSulfurDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPSulfurDioxideConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSulfurDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPSulfurDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfurDioxideConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                     this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfurDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPSulfurDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfurDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPSulfurDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPSulfurDioxideConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSulfurDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPSulfurDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfurDioxideConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfurDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPSulfurDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfurDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPSulfurDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPSulfurDioxideConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSulfurDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPSulfurDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfurDioxideConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfurDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPSulfurDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfurDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPSulfurDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPSulfurDioxideConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSulfurDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPSulfurDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfurDioxideConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                       this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfurDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPSulfurDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfurDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPSulfurDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPSulfurDioxideConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSulfurDioxideConcentrationMeasurementEventListAttributeCallback::
    CHIPSulfurDioxideConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfurDioxideConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfurDioxideConcentrationMeasurementEventListAttributeCallback::
    ~CHIPSulfurDioxideConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfurDioxideConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPSulfurDioxideConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfurDioxideConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSulfurDioxideConcentrationMeasurementAttributeListAttributeCallback::
    CHIPSulfurDioxideConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfurDioxideConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfurDioxideConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPSulfurDioxideConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfurDioxideConcentrationMeasurementAttributeListAttributeCallback::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<CHIPSulfurDioxideConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfurDioxideConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDissolvedOxygenConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPDissolvedOxygenConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDissolvedOxygenConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDissolvedOxygenConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPDissolvedOxygenConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDissolvedOxygenConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPDissolvedOxygenConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDissolvedOxygenConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPDissolvedOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPDissolvedOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDissolvedOxygenConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDissolvedOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPDissolvedOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDissolvedOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPDissolvedOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPDissolvedOxygenConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPDissolvedOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPDissolvedOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDissolvedOxygenConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDissolvedOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPDissolvedOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDissolvedOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPDissolvedOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPDissolvedOxygenConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPDissolvedOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPDissolvedOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDissolvedOxygenConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                       this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDissolvedOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPDissolvedOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDissolvedOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPDissolvedOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPDissolvedOxygenConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPDissolvedOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPDissolvedOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDissolvedOxygenConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDissolvedOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPDissolvedOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDissolvedOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPDissolvedOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPDissolvedOxygenConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPDissolvedOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPDissolvedOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDissolvedOxygenConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDissolvedOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPDissolvedOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDissolvedOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPDissolvedOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPDissolvedOxygenConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDissolvedOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPDissolvedOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDissolvedOxygenConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                         this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDissolvedOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPDissolvedOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDissolvedOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPDissolvedOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPDissolvedOxygenConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDissolvedOxygenConcentrationMeasurementEventListAttributeCallback::
    CHIPDissolvedOxygenConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDissolvedOxygenConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDissolvedOxygenConcentrationMeasurementEventListAttributeCallback::
    ~CHIPDissolvedOxygenConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDissolvedOxygenConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPDissolvedOxygenConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDissolvedOxygenConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPDissolvedOxygenConcentrationMeasurementAttributeListAttributeCallback::
    CHIPDissolvedOxygenConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPDissolvedOxygenConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPDissolvedOxygenConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPDissolvedOxygenConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPDissolvedOxygenConcentrationMeasurementAttributeListAttributeCallback::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<CHIPDissolvedOxygenConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPDissolvedOxygenConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromateConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPBromateConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromateConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromateConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPBromateConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromateConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPBromateConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromateConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromateConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPBromateConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromateConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromateConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPBromateConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromateConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPBromateConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromateConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromateConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPBromateConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromateConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromateConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPBromateConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromateConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPBromateConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromateConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromateConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPBromateConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromateConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromateConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPBromateConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromateConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPBromateConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromateConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromateConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPBromateConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromateConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromateConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPBromateConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromateConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPBromateConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromateConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromateConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPBromateConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromateConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromateConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPBromateConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromateConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPBromateConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromateConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromateConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPBromateConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromateConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromateConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPBromateConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromateConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPBromateConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromateConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromateConcentrationMeasurementEventListAttributeCallback::CHIPBromateConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromateConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromateConcentrationMeasurementEventListAttributeCallback::~CHIPBromateConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromateConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBromateConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromateConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromateConcentrationMeasurementAttributeListAttributeCallback::
    CHIPBromateConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromateConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromateConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPBromateConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromateConcentrationMeasurementAttributeListAttributeCallback::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<CHIPBromateConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromateConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChloraminesConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPChloraminesConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloraminesConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloraminesConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPChloraminesConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloraminesConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPChloraminesConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloraminesConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChloraminesConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPChloraminesConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloraminesConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloraminesConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPChloraminesConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloraminesConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPChloraminesConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloraminesConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChloraminesConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPChloraminesConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloraminesConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloraminesConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPChloraminesConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloraminesConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPChloraminesConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloraminesConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChloraminesConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPChloraminesConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloraminesConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloraminesConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPChloraminesConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloraminesConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPChloraminesConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloraminesConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChloraminesConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPChloraminesConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloraminesConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloraminesConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPChloraminesConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloraminesConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPChloraminesConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChloraminesConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChloraminesConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPChloraminesConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloraminesConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloraminesConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPChloraminesConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloraminesConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPChloraminesConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChloraminesConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChloraminesConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPChloraminesConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloraminesConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                     this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloraminesConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPChloraminesConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloraminesConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPChloraminesConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChloraminesConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChloraminesConcentrationMeasurementEventListAttributeCallback::
    CHIPChloraminesConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloraminesConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloraminesConcentrationMeasurementEventListAttributeCallback::
    ~CHIPChloraminesConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloraminesConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPChloraminesConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloraminesConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChloraminesConcentrationMeasurementAttributeListAttributeCallback::
    CHIPChloraminesConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloraminesConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloraminesConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPChloraminesConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloraminesConcentrationMeasurementAttributeListAttributeCallback::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<CHIPChloraminesConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloraminesConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChlorineConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPChlorineConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorineConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorineConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPChlorineConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorineConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPChlorineConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChlorineConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChlorineConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPChlorineConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorineConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorineConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPChlorineConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorineConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPChlorineConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChlorineConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChlorineConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPChlorineConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorineConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorineConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPChlorineConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorineConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPChlorineConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChlorineConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChlorineConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPChlorineConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorineConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorineConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPChlorineConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorineConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPChlorineConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChlorineConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChlorineConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPChlorineConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorineConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorineConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPChlorineConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorineConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPChlorineConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChlorineConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChlorineConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPChlorineConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorineConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorineConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPChlorineConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorineConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPChlorineConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChlorineConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChlorineConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPChlorineConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorineConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorineConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPChlorineConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorineConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPChlorineConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChlorineConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChlorineConcentrationMeasurementEventListAttributeCallback::CHIPChlorineConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorineConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorineConcentrationMeasurementEventListAttributeCallback::~CHIPChlorineConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorineConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPChlorineConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChlorineConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChlorineConcentrationMeasurementAttributeListAttributeCallback::
    CHIPChlorineConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorineConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorineConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPChlorineConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorineConcentrationMeasurementAttributeListAttributeCallback::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<CHIPChlorineConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChlorineConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFecalColiformEColiConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPFecalColiformEColiConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFecalColiformEColiConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFecalColiformEColiConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPFecalColiformEColiConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFecalColiformEColiConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPFecalColiformEColiConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPFecalColiformEColiConcentrationMeasurementMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFecalColiformEColiConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPFecalColiformEColiConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFecalColiformEColiConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                         this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFecalColiformEColiConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPFecalColiformEColiConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFecalColiformEColiConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPFecalColiformEColiConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPFecalColiformEColiConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFecalColiformEColiConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPFecalColiformEColiConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFecalColiformEColiConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                         this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFecalColiformEColiConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPFecalColiformEColiConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFecalColiformEColiConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPFecalColiformEColiConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPFecalColiformEColiConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFecalColiformEColiConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPFecalColiformEColiConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFecalColiformEColiConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFecalColiformEColiConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPFecalColiformEColiConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFecalColiformEColiConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPFecalColiformEColiConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPFecalColiformEColiConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFecalColiformEColiConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPFecalColiformEColiConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFecalColiformEColiConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFecalColiformEColiConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPFecalColiformEColiConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFecalColiformEColiConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPFecalColiformEColiConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPFecalColiformEColiConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFecalColiformEColiConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPFecalColiformEColiConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFecalColiformEColiConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFecalColiformEColiConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPFecalColiformEColiConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFecalColiformEColiConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPFecalColiformEColiConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPFecalColiformEColiConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFecalColiformEColiConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPFecalColiformEColiConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFecalColiformEColiConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFecalColiformEColiConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPFecalColiformEColiConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFecalColiformEColiConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPFecalColiformEColiConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPFecalColiformEColiConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFecalColiformEColiConcentrationMeasurementEventListAttributeCallback::
    CHIPFecalColiformEColiConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFecalColiformEColiConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFecalColiformEColiConcentrationMeasurementEventListAttributeCallback::
    ~CHIPFecalColiformEColiConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFecalColiformEColiConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFecalColiformEColiConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFecalColiformEColiConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFecalColiformEColiConcentrationMeasurementAttributeListAttributeCallback::
    CHIPFecalColiformEColiConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFecalColiformEColiConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFecalColiformEColiConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPFecalColiformEColiConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFecalColiformEColiConcentrationMeasurementAttributeListAttributeCallback::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<CHIPFecalColiformEColiConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPFecalColiformEColiConcentrationMeasurementAttributeListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFluorideConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPFluorideConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFluorideConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFluorideConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPFluorideConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFluorideConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPFluorideConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFluorideConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFluorideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPFluorideConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFluorideConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFluorideConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPFluorideConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFluorideConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPFluorideConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFluorideConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFluorideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPFluorideConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFluorideConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFluorideConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPFluorideConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFluorideConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPFluorideConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFluorideConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFluorideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPFluorideConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFluorideConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFluorideConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPFluorideConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFluorideConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPFluorideConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFluorideConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFluorideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPFluorideConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFluorideConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFluorideConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPFluorideConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFluorideConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPFluorideConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFluorideConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFluorideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPFluorideConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFluorideConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFluorideConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPFluorideConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFluorideConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPFluorideConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFluorideConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFluorideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPFluorideConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFluorideConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFluorideConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPFluorideConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFluorideConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPFluorideConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFluorideConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFluorideConcentrationMeasurementEventListAttributeCallback::CHIPFluorideConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFluorideConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFluorideConcentrationMeasurementEventListAttributeCallback::~CHIPFluorideConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFluorideConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFluorideConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFluorideConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFluorideConcentrationMeasurementAttributeListAttributeCallback::
    CHIPFluorideConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFluorideConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFluorideConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPFluorideConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFluorideConcentrationMeasurementAttributeListAttributeCallback::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<CHIPFluorideConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFluorideConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHaloaceticAcidsConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPHaloaceticAcidsConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHaloaceticAcidsConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHaloaceticAcidsConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPHaloaceticAcidsConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHaloaceticAcidsConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPHaloaceticAcidsConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHaloaceticAcidsConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHaloaceticAcidsConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPHaloaceticAcidsConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHaloaceticAcidsConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHaloaceticAcidsConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPHaloaceticAcidsConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHaloaceticAcidsConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPHaloaceticAcidsConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHaloaceticAcidsConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHaloaceticAcidsConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPHaloaceticAcidsConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHaloaceticAcidsConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHaloaceticAcidsConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPHaloaceticAcidsConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHaloaceticAcidsConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPHaloaceticAcidsConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHaloaceticAcidsConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHaloaceticAcidsConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPHaloaceticAcidsConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHaloaceticAcidsConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                       this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHaloaceticAcidsConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPHaloaceticAcidsConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHaloaceticAcidsConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPHaloaceticAcidsConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHaloaceticAcidsConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHaloaceticAcidsConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPHaloaceticAcidsConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHaloaceticAcidsConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHaloaceticAcidsConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPHaloaceticAcidsConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHaloaceticAcidsConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPHaloaceticAcidsConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHaloaceticAcidsConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPHaloaceticAcidsConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPHaloaceticAcidsConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHaloaceticAcidsConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHaloaceticAcidsConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPHaloaceticAcidsConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHaloaceticAcidsConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPHaloaceticAcidsConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHaloaceticAcidsConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHaloaceticAcidsConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPHaloaceticAcidsConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHaloaceticAcidsConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                         this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHaloaceticAcidsConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPHaloaceticAcidsConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHaloaceticAcidsConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPHaloaceticAcidsConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPHaloaceticAcidsConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHaloaceticAcidsConcentrationMeasurementEventListAttributeCallback::
    CHIPHaloaceticAcidsConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHaloaceticAcidsConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHaloaceticAcidsConcentrationMeasurementEventListAttributeCallback::
    ~CHIPHaloaceticAcidsConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHaloaceticAcidsConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPHaloaceticAcidsConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHaloaceticAcidsConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPHaloaceticAcidsConcentrationMeasurementAttributeListAttributeCallback::
    CHIPHaloaceticAcidsConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPHaloaceticAcidsConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPHaloaceticAcidsConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPHaloaceticAcidsConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPHaloaceticAcidsConcentrationMeasurementAttributeListAttributeCallback::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<CHIPHaloaceticAcidsConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPHaloaceticAcidsConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalTrihalomethanesConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPTotalTrihalomethanesConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalTrihalomethanesConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalTrihalomethanesConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPTotalTrihalomethanesConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalTrihalomethanesConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPTotalTrihalomethanesConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalTrihalomethanesConcentrationMeasurementMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalTrihalomethanesConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPTotalTrihalomethanesConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalTrihalomethanesConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalTrihalomethanesConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPTotalTrihalomethanesConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalTrihalomethanesConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPTotalTrihalomethanesConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalTrihalomethanesConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalTrihalomethanesConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPTotalTrihalomethanesConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalTrihalomethanesConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalTrihalomethanesConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPTotalTrihalomethanesConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalTrihalomethanesConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPTotalTrihalomethanesConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalTrihalomethanesConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalTrihalomethanesConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPTotalTrihalomethanesConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalTrihalomethanesConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalTrihalomethanesConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPTotalTrihalomethanesConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalTrihalomethanesConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPTotalTrihalomethanesConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalTrihalomethanesConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalTrihalomethanesConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPTotalTrihalomethanesConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalTrihalomethanesConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalTrihalomethanesConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPTotalTrihalomethanesConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalTrihalomethanesConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPTotalTrihalomethanesConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalTrihalomethanesConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalTrihalomethanesConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPTotalTrihalomethanesConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalTrihalomethanesConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalTrihalomethanesConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPTotalTrihalomethanesConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalTrihalomethanesConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPTotalTrihalomethanesConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalTrihalomethanesConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalTrihalomethanesConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPTotalTrihalomethanesConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalTrihalomethanesConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalTrihalomethanesConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPTotalTrihalomethanesConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalTrihalomethanesConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPTotalTrihalomethanesConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalTrihalomethanesConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalTrihalomethanesConcentrationMeasurementEventListAttributeCallback::
    CHIPTotalTrihalomethanesConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalTrihalomethanesConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalTrihalomethanesConcentrationMeasurementEventListAttributeCallback::
    ~CHIPTotalTrihalomethanesConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalTrihalomethanesConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTotalTrihalomethanesConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalTrihalomethanesConcentrationMeasurementEventListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalTrihalomethanesConcentrationMeasurementAttributeListAttributeCallback::
    CHIPTotalTrihalomethanesConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalTrihalomethanesConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalTrihalomethanesConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPTotalTrihalomethanesConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalTrihalomethanesConcentrationMeasurementAttributeListAttributeCallback::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<CHIPTotalTrihalomethanesConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalTrihalomethanesConcentrationMeasurementAttributeListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalColiformBacteriaConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPTotalColiformBacteriaConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalColiformBacteriaConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                         this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalColiformBacteriaConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPTotalColiformBacteriaConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalColiformBacteriaConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPTotalColiformBacteriaConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalColiformBacteriaConcentrationMeasurementMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalColiformBacteriaConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPTotalColiformBacteriaConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalColiformBacteriaConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalColiformBacteriaConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPTotalColiformBacteriaConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalColiformBacteriaConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPTotalColiformBacteriaConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalColiformBacteriaConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalColiformBacteriaConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPTotalColiformBacteriaConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalColiformBacteriaConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalColiformBacteriaConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPTotalColiformBacteriaConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalColiformBacteriaConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPTotalColiformBacteriaConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalColiformBacteriaConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalColiformBacteriaConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPTotalColiformBacteriaConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalColiformBacteriaConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalColiformBacteriaConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPTotalColiformBacteriaConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalColiformBacteriaConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPTotalColiformBacteriaConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalColiformBacteriaConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalColiformBacteriaConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPTotalColiformBacteriaConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalColiformBacteriaConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalColiformBacteriaConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPTotalColiformBacteriaConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalColiformBacteriaConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPTotalColiformBacteriaConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalColiformBacteriaConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalColiformBacteriaConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPTotalColiformBacteriaConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalColiformBacteriaConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalColiformBacteriaConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPTotalColiformBacteriaConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalColiformBacteriaConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPTotalColiformBacteriaConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalColiformBacteriaConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalColiformBacteriaConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPTotalColiformBacteriaConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalColiformBacteriaConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalColiformBacteriaConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPTotalColiformBacteriaConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalColiformBacteriaConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPTotalColiformBacteriaConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalColiformBacteriaConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalColiformBacteriaConcentrationMeasurementEventListAttributeCallback::
    CHIPTotalColiformBacteriaConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalColiformBacteriaConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn,
                                                                                                                     this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalColiformBacteriaConcentrationMeasurementEventListAttributeCallback::
    ~CHIPTotalColiformBacteriaConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalColiformBacteriaConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTotalColiformBacteriaConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalColiformBacteriaConcentrationMeasurementEventListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalColiformBacteriaConcentrationMeasurementAttributeListAttributeCallback::
    CHIPTotalColiformBacteriaConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalColiformBacteriaConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn,
                                                                                                                         this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalColiformBacteriaConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPTotalColiformBacteriaConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalColiformBacteriaConcentrationMeasurementAttributeListAttributeCallback::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<CHIPTotalColiformBacteriaConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalColiformBacteriaConcentrationMeasurementAttributeListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTurbidityConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPTurbidityConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTurbidityConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTurbidityConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPTurbidityConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTurbidityConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPTurbidityConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTurbidityConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTurbidityConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPTurbidityConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTurbidityConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTurbidityConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPTurbidityConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTurbidityConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPTurbidityConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTurbidityConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTurbidityConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPTurbidityConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTurbidityConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTurbidityConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPTurbidityConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTurbidityConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPTurbidityConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTurbidityConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTurbidityConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPTurbidityConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTurbidityConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTurbidityConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPTurbidityConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTurbidityConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPTurbidityConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTurbidityConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTurbidityConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPTurbidityConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTurbidityConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTurbidityConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPTurbidityConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTurbidityConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPTurbidityConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTurbidityConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTurbidityConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPTurbidityConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTurbidityConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTurbidityConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPTurbidityConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTurbidityConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPTurbidityConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTurbidityConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTurbidityConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPTurbidityConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTurbidityConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTurbidityConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPTurbidityConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTurbidityConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPTurbidityConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTurbidityConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTurbidityConcentrationMeasurementEventListAttributeCallback::CHIPTurbidityConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTurbidityConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTurbidityConcentrationMeasurementEventListAttributeCallback::~CHIPTurbidityConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTurbidityConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTurbidityConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTurbidityConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTurbidityConcentrationMeasurementAttributeListAttributeCallback::
    CHIPTurbidityConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTurbidityConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTurbidityConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPTurbidityConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTurbidityConcentrationMeasurementAttributeListAttributeCallback::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<CHIPTurbidityConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTurbidityConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCopperConcentrationMeasurementMeasuredValueAttributeCallback::CHIPCopperConcentrationMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCopperConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCopperConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPCopperConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCopperConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPCopperConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCopperConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCopperConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPCopperConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCopperConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCopperConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPCopperConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCopperConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPCopperConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCopperConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCopperConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPCopperConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCopperConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCopperConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPCopperConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCopperConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPCopperConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCopperConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCopperConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPCopperConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCopperConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCopperConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPCopperConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCopperConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPCopperConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCopperConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCopperConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPCopperConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCopperConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCopperConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPCopperConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCopperConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPCopperConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCopperConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPCopperConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPCopperConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCopperConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCopperConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPCopperConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCopperConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPCopperConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCopperConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCopperConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPCopperConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCopperConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCopperConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPCopperConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCopperConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPCopperConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCopperConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCopperConcentrationMeasurementEventListAttributeCallback::CHIPCopperConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCopperConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCopperConcentrationMeasurementEventListAttributeCallback::~CHIPCopperConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCopperConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPCopperConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCopperConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPCopperConcentrationMeasurementAttributeListAttributeCallback::CHIPCopperConcentrationMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPCopperConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPCopperConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPCopperConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPCopperConcentrationMeasurementAttributeListAttributeCallback::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<CHIPCopperConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPCopperConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLeadConcentrationMeasurementMeasuredValueAttributeCallback::CHIPLeadConcentrationMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLeadConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLeadConcentrationMeasurementMeasuredValueAttributeCallback::~CHIPLeadConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLeadConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPLeadConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLeadConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPLeadConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPLeadConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLeadConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLeadConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPLeadConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLeadConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPLeadConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLeadConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPLeadConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPLeadConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLeadConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLeadConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPLeadConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLeadConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPLeadConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLeadConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPLeadConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPLeadConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLeadConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLeadConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPLeadConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLeadConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPLeadConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLeadConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPLeadConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPLeadConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLeadConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLeadConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPLeadConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLeadConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPLeadConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLeadConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPLeadConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPLeadConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLeadConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLeadConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPLeadConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLeadConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPLeadConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLeadConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLeadConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPLeadConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLeadConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLeadConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPLeadConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLeadConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPLeadConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLeadConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLeadConcentrationMeasurementEventListAttributeCallback::CHIPLeadConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLeadConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLeadConcentrationMeasurementEventListAttributeCallback::~CHIPLeadConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLeadConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPLeadConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLeadConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPLeadConcentrationMeasurementAttributeListAttributeCallback::CHIPLeadConcentrationMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLeadConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLeadConcentrationMeasurementAttributeListAttributeCallback::~CHIPLeadConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLeadConcentrationMeasurementAttributeListAttributeCallback::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<CHIPLeadConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLeadConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPManganeseConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPManganeseConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPManganeseConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPManganeseConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPManganeseConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPManganeseConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPManganeseConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPManganeseConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPManganeseConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPManganeseConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPManganeseConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPManganeseConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPManganeseConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPManganeseConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPManganeseConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPManganeseConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPManganeseConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPManganeseConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPManganeseConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPManganeseConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPManganeseConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPManganeseConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPManganeseConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPManganeseConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPManganeseConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPManganeseConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPManganeseConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPManganeseConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPManganeseConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPManganeseConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPManganeseConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPManganeseConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPManganeseConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPManganeseConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPManganeseConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPManganeseConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPManganeseConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPManganeseConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPManganeseConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPManganeseConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPManganeseConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPManganeseConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPManganeseConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPManganeseConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPManganeseConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPManganeseConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPManganeseConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPManganeseConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPManganeseConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPManganeseConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPManganeseConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPManganeseConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPManganeseConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPManganeseConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPManganeseConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPManganeseConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPManganeseConcentrationMeasurementEventListAttributeCallback::CHIPManganeseConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPManganeseConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPManganeseConcentrationMeasurementEventListAttributeCallback::~CHIPManganeseConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPManganeseConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPManganeseConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPManganeseConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPManganeseConcentrationMeasurementAttributeListAttributeCallback::
    CHIPManganeseConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPManganeseConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPManganeseConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPManganeseConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPManganeseConcentrationMeasurementAttributeListAttributeCallback::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<CHIPManganeseConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPManganeseConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSulfateConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPSulfateConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfateConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfateConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPSulfateConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfateConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPSulfateConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfateConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSulfateConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPSulfateConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfateConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfateConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPSulfateConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfateConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPSulfateConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfateConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSulfateConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPSulfateConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfateConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfateConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPSulfateConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfateConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPSulfateConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfateConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSulfateConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPSulfateConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfateConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfateConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPSulfateConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfateConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPSulfateConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfateConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSulfateConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPSulfateConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfateConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfateConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPSulfateConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfateConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPSulfateConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfateConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSulfateConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPSulfateConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfateConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfateConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPSulfateConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfateConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPSulfateConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfateConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSulfateConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPSulfateConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfateConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfateConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPSulfateConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfateConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPSulfateConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfateConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSulfateConcentrationMeasurementEventListAttributeCallback::CHIPSulfateConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfateConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfateConcentrationMeasurementEventListAttributeCallback::~CHIPSulfateConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfateConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPSulfateConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfateConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSulfateConcentrationMeasurementAttributeListAttributeCallback::
    CHIPSulfateConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSulfateConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSulfateConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPSulfateConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSulfateConcentrationMeasurementAttributeListAttributeCallback::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<CHIPSulfateConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSulfateConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromodichloromethaneConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPBromodichloromethaneConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromodichloromethaneConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromodichloromethaneConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPBromodichloromethaneConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromodichloromethaneConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPBromodichloromethaneConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPBromodichloromethaneConcentrationMeasurementMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromodichloromethaneConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPBromodichloromethaneConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromodichloromethaneConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromodichloromethaneConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPBromodichloromethaneConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromodichloromethaneConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPBromodichloromethaneConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPBromodichloromethaneConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromodichloromethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPBromodichloromethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromodichloromethaneConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromodichloromethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPBromodichloromethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromodichloromethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPBromodichloromethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPBromodichloromethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromodichloromethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPBromodichloromethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromodichloromethaneConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromodichloromethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPBromodichloromethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromodichloromethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPBromodichloromethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPBromodichloromethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromodichloromethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPBromodichloromethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromodichloromethaneConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromodichloromethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPBromodichloromethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromodichloromethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPBromodichloromethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPBromodichloromethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromodichloromethaneConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPBromodichloromethaneConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromodichloromethaneConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromodichloromethaneConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPBromodichloromethaneConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromodichloromethaneConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPBromodichloromethaneConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPBromodichloromethaneConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromodichloromethaneConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPBromodichloromethaneConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromodichloromethaneConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromodichloromethaneConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPBromodichloromethaneConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromodichloromethaneConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPBromodichloromethaneConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPBromodichloromethaneConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromodichloromethaneConcentrationMeasurementEventListAttributeCallback::
    CHIPBromodichloromethaneConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromodichloromethaneConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromodichloromethaneConcentrationMeasurementEventListAttributeCallback::
    ~CHIPBromodichloromethaneConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromodichloromethaneConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBromodichloromethaneConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPBromodichloromethaneConcentrationMeasurementEventListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromodichloromethaneConcentrationMeasurementAttributeListAttributeCallback::
    CHIPBromodichloromethaneConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromodichloromethaneConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromodichloromethaneConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPBromodichloromethaneConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromodichloromethaneConcentrationMeasurementAttributeListAttributeCallback::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<CHIPBromodichloromethaneConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPBromodichloromethaneConcentrationMeasurementAttributeListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromoformConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPBromoformConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromoformConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromoformConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPBromoformConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromoformConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPBromoformConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromoformConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromoformConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPBromoformConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromoformConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromoformConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPBromoformConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromoformConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPBromoformConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromoformConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromoformConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPBromoformConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromoformConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromoformConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPBromoformConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromoformConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPBromoformConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromoformConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromoformConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPBromoformConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromoformConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromoformConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPBromoformConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromoformConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPBromoformConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromoformConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromoformConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPBromoformConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromoformConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromoformConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPBromoformConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromoformConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPBromoformConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPBromoformConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPBromoformConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPBromoformConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromoformConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromoformConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPBromoformConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromoformConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPBromoformConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPBromoformConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromoformConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPBromoformConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromoformConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromoformConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPBromoformConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromoformConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPBromoformConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromoformConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromoformConcentrationMeasurementEventListAttributeCallback::CHIPBromoformConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromoformConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromoformConcentrationMeasurementEventListAttributeCallback::~CHIPBromoformConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromoformConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPBromoformConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromoformConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPBromoformConcentrationMeasurementAttributeListAttributeCallback::
    CHIPBromoformConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPBromoformConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPBromoformConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPBromoformConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPBromoformConcentrationMeasurementAttributeListAttributeCallback::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<CHIPBromoformConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPBromoformConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChlorodibromomethaneConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPChlorodibromomethaneConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorodibromomethaneConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorodibromomethaneConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPChlorodibromomethaneConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorodibromomethaneConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPChlorodibromomethaneConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChlorodibromomethaneConcentrationMeasurementMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChlorodibromomethaneConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPChlorodibromomethaneConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorodibromomethaneConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorodibromomethaneConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPChlorodibromomethaneConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorodibromomethaneConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPChlorodibromomethaneConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChlorodibromomethaneConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChlorodibromomethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPChlorodibromomethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorodibromomethaneConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorodibromomethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPChlorodibromomethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorodibromomethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPChlorodibromomethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChlorodibromomethaneConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChlorodibromomethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPChlorodibromomethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorodibromomethaneConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorodibromomethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPChlorodibromomethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorodibromomethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPChlorodibromomethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChlorodibromomethaneConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChlorodibromomethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPChlorodibromomethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorodibromomethaneConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorodibromomethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPChlorodibromomethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorodibromomethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPChlorodibromomethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPChlorodibromomethaneConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChlorodibromomethaneConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPChlorodibromomethaneConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorodibromomethaneConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorodibromomethaneConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPChlorodibromomethaneConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorodibromomethaneConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPChlorodibromomethaneConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPChlorodibromomethaneConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChlorodibromomethaneConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPChlorodibromomethaneConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorodibromomethaneConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorodibromomethaneConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPChlorodibromomethaneConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorodibromomethaneConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPChlorodibromomethaneConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPChlorodibromomethaneConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChlorodibromomethaneConcentrationMeasurementEventListAttributeCallback::
    CHIPChlorodibromomethaneConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorodibromomethaneConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorodibromomethaneConcentrationMeasurementEventListAttributeCallback::
    ~CHIPChlorodibromomethaneConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorodibromomethaneConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPChlorodibromomethaneConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChlorodibromomethaneConcentrationMeasurementEventListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChlorodibromomethaneConcentrationMeasurementAttributeListAttributeCallback::
    CHIPChlorodibromomethaneConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChlorodibromomethaneConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn,
                                                                                                                        this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChlorodibromomethaneConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPChlorodibromomethaneConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChlorodibromomethaneConcentrationMeasurementAttributeListAttributeCallback::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<CHIPChlorodibromomethaneConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChlorodibromomethaneConcentrationMeasurementAttributeListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChloroformConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPChloroformConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloroformConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloroformConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPChloroformConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloroformConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPChloroformConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloroformConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChloroformConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPChloroformConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloroformConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloroformConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPChloroformConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloroformConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPChloroformConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloroformConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChloroformConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPChloroformConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloroformConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloroformConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPChloroformConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloroformConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPChloroformConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloroformConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChloroformConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPChloroformConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloroformConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloroformConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPChloroformConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloroformConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPChloroformConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloroformConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChloroformConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPChloroformConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloroformConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                     this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloroformConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPChloroformConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloroformConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPChloroformConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChloroformConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPChloroformConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPChloroformConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloroformConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                     this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloroformConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPChloroformConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloroformConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPChloroformConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChloroformConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChloroformConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPChloroformConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloroformConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloroformConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPChloroformConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloroformConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPChloroformConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPChloroformConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChloroformConcentrationMeasurementEventListAttributeCallback::CHIPChloroformConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloroformConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloroformConcentrationMeasurementEventListAttributeCallback::
    ~CHIPChloroformConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloroformConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPChloroformConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloroformConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPChloroformConcentrationMeasurementAttributeListAttributeCallback::
    CHIPChloroformConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChloroformConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChloroformConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPChloroformConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChloroformConcentrationMeasurementAttributeListAttributeCallback::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<CHIPChloroformConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChloroformConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSodiumConcentrationMeasurementMeasuredValueAttributeCallback::CHIPSodiumConcentrationMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSodiumConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSodiumConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPSodiumConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSodiumConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPSodiumConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSodiumConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSodiumConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPSodiumConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSodiumConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSodiumConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPSodiumConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSodiumConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPSodiumConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSodiumConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSodiumConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPSodiumConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSodiumConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSodiumConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPSodiumConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSodiumConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPSodiumConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSodiumConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSodiumConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPSodiumConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSodiumConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSodiumConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPSodiumConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSodiumConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPSodiumConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSodiumConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSodiumConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPSodiumConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSodiumConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSodiumConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPSodiumConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSodiumConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPSodiumConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSodiumConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPSodiumConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPSodiumConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSodiumConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSodiumConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPSodiumConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSodiumConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPSodiumConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSodiumConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSodiumConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPSodiumConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSodiumConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSodiumConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPSodiumConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSodiumConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPSodiumConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSodiumConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSodiumConcentrationMeasurementEventListAttributeCallback::CHIPSodiumConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSodiumConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSodiumConcentrationMeasurementEventListAttributeCallback::~CHIPSodiumConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSodiumConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPSodiumConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSodiumConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPSodiumConcentrationMeasurementAttributeListAttributeCallback::CHIPSodiumConcentrationMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPSodiumConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPSodiumConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPSodiumConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPSodiumConcentrationMeasurementAttributeListAttributeCallback::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<CHIPSodiumConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPSodiumConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm25ConcentrationMeasurementMeasuredValueAttributeCallback::CHIPPm25ConcentrationMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm25ConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm25ConcentrationMeasurementMeasuredValueAttributeCallback::~CHIPPm25ConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm25ConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPPm25ConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm25ConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm25ConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPPm25ConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm25ConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm25ConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPPm25ConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm25ConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPPm25ConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm25ConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm25ConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPPm25ConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm25ConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm25ConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPPm25ConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm25ConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPPm25ConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm25ConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm25ConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPPm25ConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm25ConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm25ConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPPm25ConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm25ConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPPm25ConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm25ConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm25ConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPPm25ConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm25ConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm25ConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPPm25ConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm25ConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPPm25ConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm25ConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm25ConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPPm25ConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm25ConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm25ConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPPm25ConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm25ConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPPm25ConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm25ConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm25ConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPPm25ConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm25ConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm25ConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPPm25ConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm25ConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPPm25ConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm25ConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm25ConcentrationMeasurementEventListAttributeCallback::CHIPPm25ConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm25ConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm25ConcentrationMeasurementEventListAttributeCallback::~CHIPPm25ConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm25ConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPm25ConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm25ConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm25ConcentrationMeasurementAttributeListAttributeCallback::CHIPPm25ConcentrationMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm25ConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm25ConcentrationMeasurementAttributeListAttributeCallback::~CHIPPm25ConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm25ConcentrationMeasurementAttributeListAttributeCallback::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<CHIPPm25ConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm25ConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFormaldehydeConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPFormaldehydeConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFormaldehydeConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFormaldehydeConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPFormaldehydeConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFormaldehydeConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPFormaldehydeConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFormaldehydeConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFormaldehydeConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPFormaldehydeConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFormaldehydeConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFormaldehydeConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPFormaldehydeConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFormaldehydeConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPFormaldehydeConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFormaldehydeConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFormaldehydeConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPFormaldehydeConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFormaldehydeConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFormaldehydeConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPFormaldehydeConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFormaldehydeConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPFormaldehydeConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFormaldehydeConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFormaldehydeConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPFormaldehydeConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFormaldehydeConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                    this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFormaldehydeConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPFormaldehydeConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFormaldehydeConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPFormaldehydeConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPFormaldehydeConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFormaldehydeConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPFormaldehydeConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFormaldehydeConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                       this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFormaldehydeConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPFormaldehydeConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFormaldehydeConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPFormaldehydeConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPFormaldehydeConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPFormaldehydeConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPFormaldehydeConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFormaldehydeConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                       this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFormaldehydeConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPFormaldehydeConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFormaldehydeConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPFormaldehydeConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPFormaldehydeConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFormaldehydeConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPFormaldehydeConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFormaldehydeConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                      this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFormaldehydeConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPFormaldehydeConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFormaldehydeConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPFormaldehydeConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPFormaldehydeConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFormaldehydeConcentrationMeasurementEventListAttributeCallback::
    CHIPFormaldehydeConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFormaldehydeConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFormaldehydeConcentrationMeasurementEventListAttributeCallback::
    ~CHIPFormaldehydeConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFormaldehydeConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFormaldehydeConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFormaldehydeConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFormaldehydeConcentrationMeasurementAttributeListAttributeCallback::
    CHIPFormaldehydeConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFormaldehydeConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFormaldehydeConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPFormaldehydeConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFormaldehydeConcentrationMeasurementAttributeListAttributeCallback::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<CHIPFormaldehydeConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFormaldehydeConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm1ConcentrationMeasurementMeasuredValueAttributeCallback::CHIPPm1ConcentrationMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm1ConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm1ConcentrationMeasurementMeasuredValueAttributeCallback::~CHIPPm1ConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm1ConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPPm1ConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm1ConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm1ConcentrationMeasurementMinMeasuredValueAttributeCallback::CHIPPm1ConcentrationMeasurementMinMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm1ConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm1ConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPPm1ConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm1ConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPPm1ConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm1ConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm1ConcentrationMeasurementMaxMeasuredValueAttributeCallback::CHIPPm1ConcentrationMeasurementMaxMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm1ConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm1ConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPPm1ConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm1ConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPPm1ConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm1ConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm1ConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPPm1ConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm1ConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm1ConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPPm1ConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm1ConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPPm1ConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm1ConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm1ConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPPm1ConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm1ConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm1ConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPPm1ConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm1ConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPPm1ConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm1ConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm1ConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPPm1ConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm1ConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm1ConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPPm1ConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm1ConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPPm1ConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm1ConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm1ConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPPm1ConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm1ConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm1ConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPPm1ConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm1ConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPPm1ConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm1ConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm1ConcentrationMeasurementEventListAttributeCallback::CHIPPm1ConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm1ConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm1ConcentrationMeasurementEventListAttributeCallback::~CHIPPm1ConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm1ConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPm1ConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm1ConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm1ConcentrationMeasurementAttributeListAttributeCallback::CHIPPm1ConcentrationMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm1ConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm1ConcentrationMeasurementAttributeListAttributeCallback::~CHIPPm1ConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm1ConcentrationMeasurementAttributeListAttributeCallback::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<CHIPPm1ConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm1ConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm10ConcentrationMeasurementMeasuredValueAttributeCallback::CHIPPm10ConcentrationMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm10ConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm10ConcentrationMeasurementMeasuredValueAttributeCallback::~CHIPPm10ConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm10ConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPPm10ConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm10ConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm10ConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPPm10ConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm10ConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm10ConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPPm10ConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm10ConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPPm10ConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm10ConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm10ConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPPm10ConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm10ConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm10ConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPPm10ConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm10ConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPPm10ConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm10ConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm10ConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPPm10ConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm10ConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm10ConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPPm10ConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm10ConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPPm10ConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm10ConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm10ConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPPm10ConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm10ConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm10ConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPPm10ConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm10ConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPPm10ConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm10ConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPPm10ConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPPm10ConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm10ConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm10ConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPPm10ConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm10ConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPPm10ConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm10ConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm10ConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPPm10ConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm10ConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm10ConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPPm10ConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm10ConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPPm10ConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm10ConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm10ConcentrationMeasurementEventListAttributeCallback::CHIPPm10ConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm10ConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm10ConcentrationMeasurementEventListAttributeCallback::~CHIPPm10ConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm10ConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPPm10ConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm10ConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPPm10ConcentrationMeasurementAttributeListAttributeCallback::CHIPPm10ConcentrationMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPPm10ConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPPm10ConcentrationMeasurementAttributeListAttributeCallback::~CHIPPm10ConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPPm10ConcentrationMeasurementAttributeListAttributeCallback::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<CHIPPm10ConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPPm10ConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMeasuredValueAttributeCallback::
    CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMeasuredValueAttributeCallback::
    ~CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMeasuredValueAttributeCallback,
                    decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMeasuredValueAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMinMeasuredValueAttributeCallback,
                    decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMaxMeasuredValueAttributeCallback,
                    decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback,
                                                                                                bool keepAlive) :
    chip::Callback::Callback<
        CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementPeakMeasuredValueAttributeCallback,
                    decltype(&maybeDestroy)>
        cppCallback(reinterpret_cast<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(
                        context),
                    maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<
        CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAverageMeasuredValueAttributeCallback,
                    decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(
                context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<
        CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn,
                                                                                                                   this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementGeneratedCommandListAttributeCallback,
                    decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementGeneratedCommandListAttributeCallback *>(
                context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                  bool keepAlive) :
    chip::Callback::Callback<
        CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAcceptedCommandListAttributeCallback,
                    decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAcceptedCommandListAttributeCallback *>(
                context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementEventListAttributeCallback::
    CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementClusterEventListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementEventListAttributeCallback::
    ~CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementEventListAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeListAttributeCallback::
    CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementClusterAttributeListAttributeCallbackType>(
        CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeListAttributeCallback::
    ~CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeListAttributeCallback::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<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeListAttributeCallback,
                    decltype(&maybeDestroy)>
        cppCallback(
            reinterpret_cast<CHIPTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeListAttributeCallback *>(context),
            maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPRadonConcentrationMeasurementMeasuredValueAttributeCallback::CHIPRadonConcentrationMeasurementMeasuredValueAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRadonConcentrationMeasurementClusterMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRadonConcentrationMeasurementMeasuredValueAttributeCallback::~CHIPRadonConcentrationMeasurementMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRadonConcentrationMeasurementMeasuredValueAttributeCallback::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<CHIPRadonConcentrationMeasurementMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRadonConcentrationMeasurementMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPRadonConcentrationMeasurementMinMeasuredValueAttributeCallback::
    CHIPRadonConcentrationMeasurementMinMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRadonConcentrationMeasurementClusterMinMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRadonConcentrationMeasurementMinMeasuredValueAttributeCallback::
    ~CHIPRadonConcentrationMeasurementMinMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRadonConcentrationMeasurementMinMeasuredValueAttributeCallback::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<CHIPRadonConcentrationMeasurementMinMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRadonConcentrationMeasurementMinMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPRadonConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    CHIPRadonConcentrationMeasurementMaxMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRadonConcentrationMeasurementClusterMaxMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRadonConcentrationMeasurementMaxMeasuredValueAttributeCallback::
    ~CHIPRadonConcentrationMeasurementMaxMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRadonConcentrationMeasurementMaxMeasuredValueAttributeCallback::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<CHIPRadonConcentrationMeasurementMaxMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRadonConcentrationMeasurementMaxMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPRadonConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    CHIPRadonConcentrationMeasurementPeakMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRadonConcentrationMeasurementClusterPeakMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRadonConcentrationMeasurementPeakMeasuredValueAttributeCallback::
    ~CHIPRadonConcentrationMeasurementPeakMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRadonConcentrationMeasurementPeakMeasuredValueAttributeCallback::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<CHIPRadonConcentrationMeasurementPeakMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRadonConcentrationMeasurementPeakMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPRadonConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    CHIPRadonConcentrationMeasurementAverageMeasuredValueAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRadonConcentrationMeasurementClusterAverageMeasuredValueAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRadonConcentrationMeasurementAverageMeasuredValueAttributeCallback::
    ~CHIPRadonConcentrationMeasurementAverageMeasuredValueAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRadonConcentrationMeasurementAverageMeasuredValueAttributeCallback::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<CHIPRadonConcentrationMeasurementAverageMeasuredValueAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRadonConcentrationMeasurementAverageMeasuredValueAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPRadonConcentrationMeasurementGeneratedCommandListAttributeCallback::
    CHIPRadonConcentrationMeasurementGeneratedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRadonConcentrationMeasurementClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRadonConcentrationMeasurementGeneratedCommandListAttributeCallback::
    ~CHIPRadonConcentrationMeasurementGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRadonConcentrationMeasurementGeneratedCommandListAttributeCallback::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<CHIPRadonConcentrationMeasurementGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRadonConcentrationMeasurementGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPRadonConcentrationMeasurementAcceptedCommandListAttributeCallback::
    CHIPRadonConcentrationMeasurementAcceptedCommandListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRadonConcentrationMeasurementClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRadonConcentrationMeasurementAcceptedCommandListAttributeCallback::
    ~CHIPRadonConcentrationMeasurementAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRadonConcentrationMeasurementAcceptedCommandListAttributeCallback::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<CHIPRadonConcentrationMeasurementAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRadonConcentrationMeasurementAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPRadonConcentrationMeasurementEventListAttributeCallback::CHIPRadonConcentrationMeasurementEventListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRadonConcentrationMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRadonConcentrationMeasurementEventListAttributeCallback::~CHIPRadonConcentrationMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRadonConcentrationMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPRadonConcentrationMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRadonConcentrationMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPRadonConcentrationMeasurementAttributeListAttributeCallback::CHIPRadonConcentrationMeasurementAttributeListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPRadonConcentrationMeasurementClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPRadonConcentrationMeasurementAttributeListAttributeCallback::~CHIPRadonConcentrationMeasurementAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPRadonConcentrationMeasurementAttributeListAttributeCallback::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<CHIPRadonConcentrationMeasurementAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPRadonConcentrationMeasurementAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPWakeOnLanEventListAttributeCallback::CHIPWakeOnLanEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPWakeOnLanClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPWakeOnLanEventListAttributeCallback::~CHIPWakeOnLanEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPWakeOnLanEventListAttributeCallback::CallbackFn(void * context,
                                                         const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPWakeOnLanEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPWakeOnLanEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::ChannelInfoStruct::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;
            LogErrorOnFailure(
                chip::JniReferences::GetInstance().CharToStringUTF(entry_0.name.Value(), newElement_0_nameInsideOptional));
            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;
            LogErrorOnFailure(
                chip::JniReferences::GetInstance().CharToStringUTF(entry_0.callSign.Value(), newElement_0_callSignInsideOptional));
            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;
            LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.affiliateCallSign.Value(),
                                                                                 newElement_0_affiliateCallSignInsideOptional));
            chip::JniReferences::GetInstance().CreateOptional(newElement_0_affiliateCallSignInsideOptional,
                                                              newElement_0_affiliateCallSign);
        }

        jclass channelInfoStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$ChannelClusterChannelInfoStruct", channelInfoStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$ChannelClusterChannelInfoStruct");
            return;
        }
        jmethodID channelInfoStructStructCtor_1 = env->GetMethodID(
            channelInfoStructStructClass_1, "<init>",
            "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V");
        if (channelInfoStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$ChannelClusterChannelInfoStruct constructor");
            return;
        }

        newElement_0 =
            env->NewObject(channelInfoStructStructClass_1, channelInfoStructStructCtor_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);
}

CHIPChannelEventListAttributeCallback::CHIPChannelEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPChannelClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPChannelEventListAttributeCallback::~CHIPChannelEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPChannelEventListAttributeCallback::CallbackFn(void * context,
                                                       const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPChannelEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPChannelEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::TargetInfoStruct::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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.name, newElement_0_name));

        jclass targetInfoStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$TargetNavigatorClusterTargetInfoStruct", targetInfoStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$TargetNavigatorClusterTargetInfoStruct");
            return;
        }
        jmethodID targetInfoStructStructCtor_1 =
            env->GetMethodID(targetInfoStructStructClass_1, "<init>", "(Ljava/lang/Integer;Ljava/lang/String;)V");
        if (targetInfoStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$TargetNavigatorClusterTargetInfoStruct constructor");
            return;
        }

        newElement_0 =
            env->NewObject(targetInfoStructStructClass_1, targetInfoStructStructCtor_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);
}

CHIPTargetNavigatorEventListAttributeCallback::CHIPTargetNavigatorEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPTargetNavigatorClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPTargetNavigatorEventListAttributeCallback::~CHIPTargetNavigatorEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPTargetNavigatorEventListAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPTargetNavigatorEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPTargetNavigatorEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPMediaPlaybackEventListAttributeCallback::CHIPMediaPlaybackEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPMediaPlaybackClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaPlaybackEventListAttributeCallback::~CHIPMediaPlaybackEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaPlaybackEventListAttributeCallback::CallbackFn(void * context,
                                                             const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPMediaPlaybackEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaPlaybackEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::InputInfoStruct::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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.name, newElement_0_name));
        jobject newElement_0_description;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.description, newElement_0_description));

        jclass inputInfoStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$MediaInputClusterInputInfoStruct", inputInfoStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$MediaInputClusterInputInfoStruct");
            return;
        }
        jmethodID inputInfoStructStructCtor_1 =
            env->GetMethodID(inputInfoStructStructClass_1, "<init>",
                             "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;)V");
        if (inputInfoStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$MediaInputClusterInputInfoStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(inputInfoStructStructClass_1, inputInfoStructStructCtor_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);
}

CHIPMediaInputEventListAttributeCallback::CHIPMediaInputEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPMediaInputClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPMediaInputEventListAttributeCallback::~CHIPMediaInputEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPMediaInputEventListAttributeCallback::CallbackFn(void * context,
                                                          const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPMediaInputEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPMediaInputEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPLowPowerEventListAttributeCallback::CHIPLowPowerEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPLowPowerClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPLowPowerEventListAttributeCallback::~CHIPLowPowerEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPLowPowerEventListAttributeCallback::CallbackFn(void * context,
                                                        const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPLowPowerEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPLowPowerEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPKeypadInputEventListAttributeCallback::CHIPKeypadInputEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPKeypadInputClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPKeypadInputEventListAttributeCallback::~CHIPKeypadInputEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPKeypadInputEventListAttributeCallback::CallbackFn(void * context,
                                                           const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPKeypadInputEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPKeypadInputEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0, newElement_0));
        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);
}

CHIPContentLauncherEventListAttributeCallback::CHIPContentLauncherEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPContentLauncherClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPContentLauncherEventListAttributeCallback::~CHIPContentLauncherEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPContentLauncherEventListAttributeCallback::CallbackFn(void * context,
                                                               const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPContentLauncherEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPContentLauncherEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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::OutputInfoStruct::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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.name, newElement_0_name));

        jclass outputInfoStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$AudioOutputClusterOutputInfoStruct", outputInfoStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$AudioOutputClusterOutputInfoStruct");
            return;
        }
        jmethodID outputInfoStructStructCtor_1 = env->GetMethodID(outputInfoStructStructClass_1, "<init>",
                                                                  "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)V");
        if (outputInfoStructStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$AudioOutputClusterOutputInfoStruct constructor");
            return;
        }

        newElement_0 = env->NewObject(outputInfoStructStructClass_1, outputInfoStructStructCtor_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);
}

CHIPAudioOutputEventListAttributeCallback::CHIPAudioOutputEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAudioOutputClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAudioOutputEventListAttributeCallback::~CHIPAudioOutputEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAudioOutputEventListAttributeCallback::CallbackFn(void * context,
                                                           const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAudioOutputEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAudioOutputEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPApplicationLauncherEventListAttributeCallback::CHIPApplicationLauncherEventListAttributeCallback(jobject javaCallback,
                                                                                                     bool keepAlive) :
    chip::Callback::Callback<CHIPApplicationLauncherClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPApplicationLauncherEventListAttributeCallback::~CHIPApplicationLauncherEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPApplicationLauncherEventListAttributeCallback::CallbackFn(void * context,
                                                                   const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPApplicationLauncherEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPApplicationLauncherEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

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);
}

CHIPApplicationBasicEventListAttributeCallback::CHIPApplicationBasicEventListAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPApplicationBasicClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPApplicationBasicEventListAttributeCallback::~CHIPApplicationBasicEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPApplicationBasicEventListAttributeCallback::CallbackFn(void * context,
                                                                const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPApplicationBasicEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPApplicationBasicEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPAccountLoginEventListAttributeCallback::CHIPAccountLoginEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPAccountLoginClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPAccountLoginEventListAttributeCallback::~CHIPAccountLoginEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPAccountLoginEventListAttributeCallback::CallbackFn(void * context,
                                                            const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPAccountLoginEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPAccountLoginEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPElectricalMeasurementEventListAttributeCallback::CHIPElectricalMeasurementEventListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPElectricalMeasurementClusterEventListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPElectricalMeasurementEventListAttributeCallback::~CHIPElectricalMeasurementEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPElectricalMeasurementEventListAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPElectricalMeasurementEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPElectricalMeasurementEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.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);
}

CHIPUnitTestingListInt8uAttributeCallback::CHIPUnitTestingListInt8uAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterListInt8uAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingListInt8uAttributeCallback::~CHIPUnitTestingListInt8uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingListInt8uAttributeCallback::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<CHIPUnitTestingListInt8uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingListInt8uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_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);
}

CHIPUnitTestingListOctetStringAttributeCallback::CHIPUnitTestingListOctetStringAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterListOctetStringAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingListOctetStringAttributeCallback::~CHIPUnitTestingListOctetStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingListOctetStringAttributeCallback::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<CHIPUnitTestingListOctetStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingListOctetStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::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);
}

CHIPUnitTestingListStructOctetStringAttributeCallback::CHIPUnitTestingListStructOctetStringAttributeCallback(jobject javaCallback,
                                                                                                             bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterListStructOctetStringAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingListStructOctetStringAttributeCallback::~CHIPUnitTestingListStructOctetStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingListStructOctetStringAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::UnitTesting::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<CHIPUnitTestingListStructOctetStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingListStructOctetStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::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$UnitTestingClusterTestListStructOctet", testListStructOctetStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterTestListStructOctet");
            return;
        }
        jmethodID testListStructOctetStructCtor_1 =
            env->GetMethodID(testListStructOctetStructClass_1, "<init>", "(Ljava/lang/Long;[B)V");
        if (testListStructOctetStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$UnitTestingClusterTestListStructOctet 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);
}

CHIPUnitTestingListNullablesAndOptionalsStructAttributeCallback::CHIPUnitTestingListNullablesAndOptionalsStructAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterListNullablesAndOptionalsStructAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingListNullablesAndOptionalsStructAttributeCallback::~CHIPUnitTestingListNullablesAndOptionalsStructAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingListNullablesAndOptionalsStructAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<
        chip::app::Clusters::UnitTesting::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<CHIPUnitTestingListNullablesAndOptionalsStructAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingListNullablesAndOptionalsStructAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::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
        {
            LogErrorOnFailure(
                chip::JniReferences::GetInstance().CharToStringUTF(entry_0.nullableString.Value(), newElement_0_nullableString));
        }
        jobject newElement_0_optionalString;
        if (!entry_0.optionalString.HasValue())
        {
            chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_optionalString);
        }
        else
        {
            jobject newElement_0_optionalStringInsideOptional;
            LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.optionalString.Value(),
                                                                                 newElement_0_optionalStringInsideOptional));
            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
            {
                LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(
                    entry_0.nullableOptionalString.Value().Value(), newElement_0_nullableOptionalStringInsideOptional));
            }
            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;
            LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.nullableStruct.Value().e,
                                                                                 newElement_0_nullableStruct_e));
            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$UnitTestingClusterSimpleStruct", simpleStructStructClass_3);
            if (err != CHIP_NO_ERROR)
            {
                ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterSimpleStruct");
                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$UnitTestingClusterSimpleStruct 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;
            LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.optionalStruct.Value().e,
                                                                                 newElement_0_optionalStructInsideOptional_e));
            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$UnitTestingClusterSimpleStruct", simpleStructStructClass_3);
            if (err != CHIP_NO_ERROR)
            {
                ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterSimpleStruct");
                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$UnitTestingClusterSimpleStruct 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;
                LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(
                    entry_0.nullableOptionalStruct.Value().Value().e, newElement_0_nullableOptionalStructInsideOptional_e));
                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$UnitTestingClusterSimpleStruct", simpleStructStructClass_4);
                if (err != CHIP_NO_ERROR)
                {
                    ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterSimpleStruct");
                    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$UnitTestingClusterSimpleStruct 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$UnitTestingClusterNullablesAndOptionalsStruct",
            nullablesAndOptionalsStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterNullablesAndOptionalsStruct");
            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$UnitTestingClusterSimpleStruct;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$UnitTestingClusterNullablesAndOptionalsStruct 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);
}

CHIPUnitTestingListLongOctetStringAttributeCallback::CHIPUnitTestingListLongOctetStringAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterListLongOctetStringAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingListLongOctetStringAttributeCallback::~CHIPUnitTestingListLongOctetStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingListLongOctetStringAttributeCallback::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<CHIPUnitTestingListLongOctetStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingListLongOctetStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::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);
}

CHIPUnitTestingListFabricScopedAttributeCallback::CHIPUnitTestingListFabricScopedAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterListFabricScopedAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingListFabricScopedAttributeCallback::~CHIPUnitTestingListFabricScopedAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingListFabricScopedAttributeCallback::CallbackFn(
    void * context,
    const chip::app::DataModel::DecodableList<chip::app::Clusters::UnitTesting::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<CHIPUnitTestingListFabricScopedAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingListFabricScopedAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.fabricSensitiveCharString,
                                                                             newElement_0_fabricSensitiveCharString));
        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;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.fabricSensitiveStruct.e,
                                                                             newElement_0_fabricSensitiveStruct_e));
        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$UnitTestingClusterSimpleStruct", simpleStructStructClass_2);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterSimpleStruct");
            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$UnitTestingClusterSimpleStruct 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$UnitTestingClusterTestFabricScoped", testFabricScopedStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterTestFabricScoped");
            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$UnitTestingClusterSimpleStruct;Ljava/util/ArrayList;Ljava/lang/Integer;)V");
        if (testFabricScopedStructCtor_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$UnitTestingClusterTestFabricScoped 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);
}

CHIPUnitTestingNullableBooleanAttributeCallback::CHIPUnitTestingNullableBooleanAttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableBooleanAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableBooleanAttributeCallback::~CHIPUnitTestingNullableBooleanAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableBooleanAttributeCallback::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<CHIPUnitTestingNullableBooleanAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableBooleanAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableBitmap8AttributeCallback::CHIPUnitTestingNullableBitmap8AttributeCallback(jobject javaCallback,
                                                                                                 bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableBitmap8AttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableBitmap8AttributeCallback::~CHIPUnitTestingNullableBitmap8AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableBitmap8AttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::UnitTesting::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<CHIPUnitTestingNullableBitmap8AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableBitmap8AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableBitmap16AttributeCallback::CHIPUnitTestingNullableBitmap16AttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableBitmap16AttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableBitmap16AttributeCallback::~CHIPUnitTestingNullableBitmap16AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableBitmap16AttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::UnitTesting::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<CHIPUnitTestingNullableBitmap16AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableBitmap16AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableBitmap32AttributeCallback::CHIPUnitTestingNullableBitmap32AttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableBitmap32AttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableBitmap32AttributeCallback::~CHIPUnitTestingNullableBitmap32AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableBitmap32AttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::UnitTesting::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<CHIPUnitTestingNullableBitmap32AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableBitmap32AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableBitmap64AttributeCallback::CHIPUnitTestingNullableBitmap64AttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableBitmap64AttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableBitmap64AttributeCallback::~CHIPUnitTestingNullableBitmap64AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableBitmap64AttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::UnitTesting::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<CHIPUnitTestingNullableBitmap64AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableBitmap64AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt8uAttributeCallback::CHIPUnitTestingNullableInt8uAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt8uAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt8uAttributeCallback::~CHIPUnitTestingNullableInt8uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt8uAttributeCallback::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<CHIPUnitTestingNullableInt8uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt8uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt16uAttributeCallback::CHIPUnitTestingNullableInt16uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt16uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt16uAttributeCallback::~CHIPUnitTestingNullableInt16uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt16uAttributeCallback::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<CHIPUnitTestingNullableInt16uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt16uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt24uAttributeCallback::CHIPUnitTestingNullableInt24uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt24uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt24uAttributeCallback::~CHIPUnitTestingNullableInt24uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt24uAttributeCallback::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<CHIPUnitTestingNullableInt24uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt24uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt32uAttributeCallback::CHIPUnitTestingNullableInt32uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt32uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt32uAttributeCallback::~CHIPUnitTestingNullableInt32uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt32uAttributeCallback::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<CHIPUnitTestingNullableInt32uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt32uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt40uAttributeCallback::CHIPUnitTestingNullableInt40uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt40uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt40uAttributeCallback::~CHIPUnitTestingNullableInt40uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt40uAttributeCallback::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<CHIPUnitTestingNullableInt40uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt40uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt48uAttributeCallback::CHIPUnitTestingNullableInt48uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt48uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt48uAttributeCallback::~CHIPUnitTestingNullableInt48uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt48uAttributeCallback::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<CHIPUnitTestingNullableInt48uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt48uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt56uAttributeCallback::CHIPUnitTestingNullableInt56uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt56uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt56uAttributeCallback::~CHIPUnitTestingNullableInt56uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt56uAttributeCallback::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<CHIPUnitTestingNullableInt56uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt56uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt64uAttributeCallback::CHIPUnitTestingNullableInt64uAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt64uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt64uAttributeCallback::~CHIPUnitTestingNullableInt64uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt64uAttributeCallback::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<CHIPUnitTestingNullableInt64uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt64uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt8sAttributeCallback::CHIPUnitTestingNullableInt8sAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt8sAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt8sAttributeCallback::~CHIPUnitTestingNullableInt8sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt8sAttributeCallback::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<CHIPUnitTestingNullableInt8sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt8sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt16sAttributeCallback::CHIPUnitTestingNullableInt16sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt16sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt16sAttributeCallback::~CHIPUnitTestingNullableInt16sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt16sAttributeCallback::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<CHIPUnitTestingNullableInt16sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt16sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt24sAttributeCallback::CHIPUnitTestingNullableInt24sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt24sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt24sAttributeCallback::~CHIPUnitTestingNullableInt24sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt24sAttributeCallback::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<CHIPUnitTestingNullableInt24sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt24sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt32sAttributeCallback::CHIPUnitTestingNullableInt32sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt32sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt32sAttributeCallback::~CHIPUnitTestingNullableInt32sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt32sAttributeCallback::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<CHIPUnitTestingNullableInt32sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt32sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt40sAttributeCallback::CHIPUnitTestingNullableInt40sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt40sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt40sAttributeCallback::~CHIPUnitTestingNullableInt40sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt40sAttributeCallback::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<CHIPUnitTestingNullableInt40sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt40sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt48sAttributeCallback::CHIPUnitTestingNullableInt48sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt48sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt48sAttributeCallback::~CHIPUnitTestingNullableInt48sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt48sAttributeCallback::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<CHIPUnitTestingNullableInt48sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt48sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt56sAttributeCallback::CHIPUnitTestingNullableInt56sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt56sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt56sAttributeCallback::~CHIPUnitTestingNullableInt56sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt56sAttributeCallback::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<CHIPUnitTestingNullableInt56sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt56sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableInt64sAttributeCallback::CHIPUnitTestingNullableInt64sAttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableInt64sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableInt64sAttributeCallback::~CHIPUnitTestingNullableInt64sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableInt64sAttributeCallback::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<CHIPUnitTestingNullableInt64sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableInt64sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableEnum8AttributeCallback::CHIPUnitTestingNullableEnum8AttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableEnum8AttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableEnum8AttributeCallback::~CHIPUnitTestingNullableEnum8AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableEnum8AttributeCallback::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<CHIPUnitTestingNullableEnum8AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableEnum8AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableEnum16AttributeCallback::CHIPUnitTestingNullableEnum16AttributeCallback(jobject javaCallback,
                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableEnum16AttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableEnum16AttributeCallback::~CHIPUnitTestingNullableEnum16AttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableEnum16AttributeCallback::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<CHIPUnitTestingNullableEnum16AttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableEnum16AttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableFloatSingleAttributeCallback::CHIPUnitTestingNullableFloatSingleAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableFloatSingleAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableFloatSingleAttributeCallback::~CHIPUnitTestingNullableFloatSingleAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableFloatSingleAttributeCallback::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<CHIPUnitTestingNullableFloatSingleAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableFloatSingleAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableFloatDoubleAttributeCallback::CHIPUnitTestingNullableFloatDoubleAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableFloatDoubleAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableFloatDoubleAttributeCallback::~CHIPUnitTestingNullableFloatDoubleAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableFloatDoubleAttributeCallback::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<CHIPUnitTestingNullableFloatDoubleAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableFloatDoubleAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableOctetStringAttributeCallback::CHIPUnitTestingNullableOctetStringAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableOctetStringAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableOctetStringAttributeCallback::~CHIPUnitTestingNullableOctetStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableOctetStringAttributeCallback::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<CHIPUnitTestingNullableOctetStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableOctetStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(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);
}

CHIPUnitTestingNullableCharStringAttributeCallback::CHIPUnitTestingNullableCharStringAttributeCallback(jobject javaCallback,
                                                                                                       bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableCharStringAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableCharStringAttributeCallback::~CHIPUnitTestingNullableCharStringAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableCharStringAttributeCallback::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<CHIPUnitTestingNullableCharStringAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableCharStringAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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
    {
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(value.Value(), javaValue));
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}

CHIPUnitTestingNullableEnumAttrAttributeCallback::CHIPUnitTestingNullableEnumAttrAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableEnumAttrAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableEnumAttrAttributeCallback::~CHIPUnitTestingNullableEnumAttrAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableEnumAttrAttributeCallback::CallbackFn(
    void * context, const chip::app::DataModel::Nullable<chip::app::Clusters::UnitTesting::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<CHIPUnitTestingNullableEnumAttrAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableEnumAttrAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableRangeRestrictedInt8uAttributeCallback::CHIPUnitTestingNullableRangeRestrictedInt8uAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableRangeRestrictedInt8uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableRangeRestrictedInt8uAttributeCallback::~CHIPUnitTestingNullableRangeRestrictedInt8uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableRangeRestrictedInt8uAttributeCallback::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<CHIPUnitTestingNullableRangeRestrictedInt8uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableRangeRestrictedInt8uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableRangeRestrictedInt8sAttributeCallback::CHIPUnitTestingNullableRangeRestrictedInt8sAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableRangeRestrictedInt8sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableRangeRestrictedInt8sAttributeCallback::~CHIPUnitTestingNullableRangeRestrictedInt8sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableRangeRestrictedInt8sAttributeCallback::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<CHIPUnitTestingNullableRangeRestrictedInt8sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableRangeRestrictedInt8sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableRangeRestrictedInt16uAttributeCallback::CHIPUnitTestingNullableRangeRestrictedInt16uAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableRangeRestrictedInt16uAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableRangeRestrictedInt16uAttributeCallback::~CHIPUnitTestingNullableRangeRestrictedInt16uAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableRangeRestrictedInt16uAttributeCallback::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<CHIPUnitTestingNullableRangeRestrictedInt16uAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableRangeRestrictedInt16uAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingNullableRangeRestrictedInt16sAttributeCallback::CHIPUnitTestingNullableRangeRestrictedInt16sAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterNullableRangeRestrictedInt16sAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingNullableRangeRestrictedInt16sAttributeCallback::~CHIPUnitTestingNullableRangeRestrictedInt16sAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingNullableRangeRestrictedInt16sAttributeCallback::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<CHIPUnitTestingNullableRangeRestrictedInt16sAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingNullableRangeRestrictedInt16sAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   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);
}

CHIPUnitTestingGeneratedCommandListAttributeCallback::CHIPUnitTestingGeneratedCommandListAttributeCallback(jobject javaCallback,
                                                                                                           bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingGeneratedCommandListAttributeCallback::~CHIPUnitTestingGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingGeneratedCommandListAttributeCallback::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<CHIPUnitTestingGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPUnitTestingAcceptedCommandListAttributeCallback::CHIPUnitTestingAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                         bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingAcceptedCommandListAttributeCallback::~CHIPUnitTestingAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingAcceptedCommandListAttributeCallback::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<CHIPUnitTestingAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPUnitTestingEventListAttributeCallback::CHIPUnitTestingEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingEventListAttributeCallback::~CHIPUnitTestingEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingEventListAttributeCallback::CallbackFn(void * context,
                                                           const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPUnitTestingEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPUnitTestingAttributeListAttributeCallback::CHIPUnitTestingAttributeListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPUnitTestingClusterAttributeListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPUnitTestingAttributeListAttributeCallback::~CHIPUnitTestingAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPUnitTestingAttributeListAttributeCallback::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<CHIPUnitTestingAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPUnitTestingAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFaultInjectionGeneratedCommandListAttributeCallback::CHIPFaultInjectionGeneratedCommandListAttributeCallback(
    jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFaultInjectionClusterGeneratedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFaultInjectionGeneratedCommandListAttributeCallback::~CHIPFaultInjectionGeneratedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFaultInjectionGeneratedCommandListAttributeCallback::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<CHIPFaultInjectionGeneratedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFaultInjectionGeneratedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFaultInjectionAcceptedCommandListAttributeCallback::CHIPFaultInjectionAcceptedCommandListAttributeCallback(jobject javaCallback,
                                                                                                               bool keepAlive) :
    chip::Callback::Callback<CHIPFaultInjectionClusterAcceptedCommandListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFaultInjectionAcceptedCommandListAttributeCallback::~CHIPFaultInjectionAcceptedCommandListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFaultInjectionAcceptedCommandListAttributeCallback::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<CHIPFaultInjectionAcceptedCommandListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFaultInjectionAcceptedCommandListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFaultInjectionEventListAttributeCallback::CHIPFaultInjectionEventListAttributeCallback(jobject javaCallback, bool keepAlive) :
    chip::Callback::Callback<CHIPFaultInjectionClusterEventListAttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFaultInjectionEventListAttributeCallback::~CHIPFaultInjectionEventListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFaultInjectionEventListAttributeCallback::CallbackFn(void * context,
                                                              const chip::app::DataModel::DecodableList<chip::EventId> & list)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

    std::unique_ptr<CHIPFaultInjectionEventListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFaultInjectionEventListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}

CHIPFaultInjectionAttributeListAttributeCallback::CHIPFaultInjectionAttributeListAttributeCallback(jobject javaCallback,
                                                                                                   bool keepAlive) :
    chip::Callback::Callback<CHIPFaultInjectionClusterAttributeListAttributeCallbackType>(CallbackFn, this),
    keepAlive(keepAlive)
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

    javaCallbackRef = env->NewGlobalRef(javaCallback);
    if (javaCallbackRef == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
    }
}

CHIPFaultInjectionAttributeListAttributeCallback::~CHIPFaultInjectionAttributeListAttributeCallback()
{
    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not delete global reference for Java callback");
        return;
    }
    env->DeleteGlobalRef(javaCallbackRef);
}

void CHIPFaultInjectionAttributeListAttributeCallback::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<CHIPFaultInjectionAttributeListAttributeCallback, decltype(&maybeDestroy)> cppCallback(
        reinterpret_cast<CHIPFaultInjectionAttributeListAttributeCallback *>(context), maybeDestroy);

    // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
    javaCallbackRef = cppCallback.get()->javaCallbackRef;
    VerifyOrReturn(javaCallbackRef != nullptr,
                   ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));

    jmethodID javaMethod;
    err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));

    jobject arrayListObj;
    chip::JniReferences::GetInstance().CreateArrayList(arrayListObj);

    auto iter_arrayListObj_0 = list.begin();
    while (iter_arrayListObj_0.Next())
    {
        auto & entry_0 = iter_arrayListObj_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Long";
        std::string newElement_0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_0ClassName.c_str(),
                                                                       newElement_0CtorSignature.c_str(), entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0);
    }

    env->ExceptionClear();
    env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}
