/*
 *
 *    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 "CHIPInvokeCallbacks.h"
#include <jni/CHIPCallbackTypes.h>

#include <app-common/zap-generated/cluster-objects.h>
#include <jni.h>
#include <lib/support/CHIPJNIError.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/JniReferences.h>
#include <lib/support/JniTypeWrappers.h>
#include <platform/PlatformManager.h>

namespace chip {

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

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

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

void CHIPGroupsClusterAddGroupResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Groups::Commands::AddGroupResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPGroupsClusterAddGroupResponseCallback, void (*)(CHIPGroupsClusterAddGroupResponseCallback *)> cppCallback(
        reinterpret_cast<CHIPGroupsClusterAddGroupResponseCallback *>(context),
        chip::Platform::Delete<CHIPGroupsClusterAddGroupResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/lang/Integer;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject GroupID;
    std::string GroupIDClassName     = "java/lang/Integer";
    std::string GroupIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIDClassName.c_str(), GroupIDCtorSignature.c_str(),
                                                                   dataResponse.groupID, GroupID);

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, GroupID);
}
CHIPGroupsClusterViewGroupResponseCallback::CHIPGroupsClusterViewGroupResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPGroupsClusterViewGroupResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPGroupsClusterViewGroupResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Groups::Commands::ViewGroupResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPGroupsClusterViewGroupResponseCallback, void (*)(CHIPGroupsClusterViewGroupResponseCallback *)> cppCallback(
        reinterpret_cast<CHIPGroupsClusterViewGroupResponseCallback *>(context),
        chip::Platform::Delete<CHIPGroupsClusterViewGroupResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject GroupID;
    std::string GroupIDClassName     = "java/lang/Integer";
    std::string GroupIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIDClassName.c_str(), GroupIDCtorSignature.c_str(),
                                                                   dataResponse.groupID, GroupID);
    jobject GroupName;
    LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.groupName, GroupName));

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, GroupID, GroupName);
}
CHIPGroupsClusterGetGroupMembershipResponseCallback::CHIPGroupsClusterGetGroupMembershipResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPGroupsClusterGetGroupMembershipResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPGroupsClusterGetGroupMembershipResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Groups::Commands::GetGroupMembershipResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPGroupsClusterGetGroupMembershipResponseCallback,
                    void (*)(CHIPGroupsClusterGetGroupMembershipResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPGroupsClusterGetGroupMembershipResponseCallback *>(context),
                    chip::Platform::Delete<CHIPGroupsClusterGetGroupMembershipResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/util/ArrayList;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Capacity;
    if (dataResponse.capacity.IsNull())
    {
        Capacity = nullptr;
    }
    else
    {
        std::string CapacityClassName     = "java/lang/Integer";
        std::string CapacityCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(CapacityClassName.c_str(), CapacityCtorSignature.c_str(),
                                                                      dataResponse.capacity.Value(), Capacity);
    }
    jobject GroupList;
    chip::JniReferences::GetInstance().CreateArrayList(GroupList);

    auto iter_GroupList_0 = dataResponse.groupList.begin();
    while (iter_GroupList_0.Next())
    {
        auto & entry_0 = iter_GroupList_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(GroupList, newElement_0);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Capacity, GroupList);
}
CHIPGroupsClusterRemoveGroupResponseCallback::CHIPGroupsClusterRemoveGroupResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPGroupsClusterRemoveGroupResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPGroupsClusterRemoveGroupResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Groups::Commands::RemoveGroupResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPGroupsClusterRemoveGroupResponseCallback, void (*)(CHIPGroupsClusterRemoveGroupResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPGroupsClusterRemoveGroupResponseCallback *>(context),
                    chip::Platform::Delete<CHIPGroupsClusterRemoveGroupResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/lang/Integer;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject GroupID;
    std::string GroupIDClassName     = "java/lang/Integer";
    std::string GroupIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIDClassName.c_str(), GroupIDCtorSignature.c_str(),
                                                                   dataResponse.groupID, GroupID);

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, GroupID);
}
CHIPScenesClusterAddSceneResponseCallback::CHIPScenesClusterAddSceneResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPScenesClusterAddSceneResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPScenesClusterAddSceneResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Scenes::Commands::AddSceneResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPScenesClusterAddSceneResponseCallback, void (*)(CHIPScenesClusterAddSceneResponseCallback *)> cppCallback(
        reinterpret_cast<CHIPScenesClusterAddSceneResponseCallback *>(context),
        chip::Platform::Delete<CHIPScenesClusterAddSceneResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject GroupID;
    std::string GroupIDClassName     = "java/lang/Integer";
    std::string GroupIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIDClassName.c_str(), GroupIDCtorSignature.c_str(),
                                                                   dataResponse.groupID, GroupID);
    jobject SceneID;
    std::string SceneIDClassName     = "java/lang/Integer";
    std::string SceneIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(SceneIDClassName.c_str(), SceneIDCtorSignature.c_str(),
                                                                  dataResponse.sceneID, SceneID);

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, GroupID, SceneID);
}
CHIPScenesClusterViewSceneResponseCallback::CHIPScenesClusterViewSceneResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPScenesClusterViewSceneResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPScenesClusterViewSceneResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Scenes::Commands::ViewSceneResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPScenesClusterViewSceneResponseCallback, void (*)(CHIPScenesClusterViewSceneResponseCallback *)> cppCallback(
        reinterpret_cast<CHIPScenesClusterViewSceneResponseCallback *>(context),
        chip::Platform::Delete<CHIPScenesClusterViewSceneResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess",
        "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject GroupID;
    std::string GroupIDClassName     = "java/lang/Integer";
    std::string GroupIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIDClassName.c_str(), GroupIDCtorSignature.c_str(),
                                                                   dataResponse.groupID, GroupID);
    jobject SceneID;
    std::string SceneIDClassName     = "java/lang/Integer";
    std::string SceneIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(SceneIDClassName.c_str(), SceneIDCtorSignature.c_str(),
                                                                  dataResponse.sceneID, SceneID);
    jobject TransitionTime;
    if (!dataResponse.transitionTime.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, TransitionTime);
    }
    else
    {
        jobject TransitionTimeInsideOptional;
        std::string TransitionTimeInsideOptionalClassName     = "java/lang/Integer";
        std::string TransitionTimeInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            TransitionTimeInsideOptionalClassName.c_str(), TransitionTimeInsideOptionalCtorSignature.c_str(),
            dataResponse.transitionTime.Value(), TransitionTimeInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(TransitionTimeInsideOptional, TransitionTime);
    }
    jobject SceneName;
    if (!dataResponse.sceneName.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, SceneName);
    }
    else
    {
        jobject SceneNameInsideOptional;
        LogErrorOnFailure(
            chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.sceneName.Value(), SceneNameInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(SceneNameInsideOptional, SceneName);
    }
    jobject ExtensionFieldSets;
    if (!dataResponse.extensionFieldSets.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, ExtensionFieldSets);
    }
    else
    {
        jobject ExtensionFieldSetsInsideOptional;
        chip::JniReferences::GetInstance().CreateArrayList(ExtensionFieldSetsInsideOptional);

        auto iter_ExtensionFieldSetsInsideOptional_1 = dataResponse.extensionFieldSets.Value().begin();
        while (iter_ExtensionFieldSetsInsideOptional_1.Next())
        {
            auto & entry_1 = iter_ExtensionFieldSetsInsideOptional_1.GetValue();
            jobject newElement_1;
            jobject newElement_1_clusterID;
            std::string newElement_1_clusterIDClassName     = "java/lang/Long";
            std::string newElement_1_clusterIDCtorSignature = "(J)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_1_clusterIDClassName.c_str(),
                                                                           newElement_1_clusterIDCtorSignature.c_str(),
                                                                           entry_1.clusterID, newElement_1_clusterID);
            jobject newElement_1_attributeValueList;
            chip::JniReferences::GetInstance().CreateArrayList(newElement_1_attributeValueList);

            auto iter_newElement_1_attributeValueList_3 = entry_1.attributeValueList.begin();
            while (iter_newElement_1_attributeValueList_3.Next())
            {
                auto & entry_3 = iter_newElement_1_attributeValueList_3.GetValue();
                jobject newElement_3;
                jobject newElement_3_attributeID;
                if (!entry_3.attributeID.HasValue())
                {
                    chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_3_attributeID);
                }
                else
                {
                    jobject newElement_3_attributeIDInsideOptional;
                    std::string newElement_3_attributeIDInsideOptionalClassName     = "java/lang/Long";
                    std::string newElement_3_attributeIDInsideOptionalCtorSignature = "(J)V";
                    chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
                        newElement_3_attributeIDInsideOptionalClassName.c_str(),
                        newElement_3_attributeIDInsideOptionalCtorSignature.c_str(), entry_3.attributeID.Value(),
                        newElement_3_attributeIDInsideOptional);
                    chip::JniReferences::GetInstance().CreateOptional(newElement_3_attributeIDInsideOptional,
                                                                      newElement_3_attributeID);
                }
                jobject newElement_3_attributeValue;
                std::string newElement_3_attributeValueClassName     = "java/lang/Long";
                std::string newElement_3_attributeValueCtorSignature = "(J)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_3_attributeValueClassName.c_str(),
                                                                               newElement_3_attributeValueCtorSignature.c_str(),
                                                                               entry_3.attributeValue, newElement_3_attributeValue);

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

                newElement_3 = env->NewObject(attributeValuePairStructClass_4, attributeValuePairStructCtor_4,
                                              newElement_3_attributeID, newElement_3_attributeValue);
                chip::JniReferences::GetInstance().AddToList(newElement_1_attributeValueList, newElement_3);
            }

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

            newElement_1 = env->NewObject(extensionFieldSetStructClass_2, extensionFieldSetStructCtor_2, newElement_1_clusterID,
                                          newElement_1_attributeValueList);
            chip::JniReferences::GetInstance().AddToList(ExtensionFieldSetsInsideOptional, newElement_1);
        }
        chip::JniReferences::GetInstance().CreateOptional(ExtensionFieldSetsInsideOptional, ExtensionFieldSets);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, GroupID, SceneID, TransitionTime, SceneName, ExtensionFieldSets);
}
CHIPScenesClusterRemoveSceneResponseCallback::CHIPScenesClusterRemoveSceneResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPScenesClusterRemoveSceneResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPScenesClusterRemoveSceneResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Scenes::Commands::RemoveSceneResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPScenesClusterRemoveSceneResponseCallback, void (*)(CHIPScenesClusterRemoveSceneResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPScenesClusterRemoveSceneResponseCallback *>(context),
                    chip::Platform::Delete<CHIPScenesClusterRemoveSceneResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject GroupID;
    std::string GroupIDClassName     = "java/lang/Integer";
    std::string GroupIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIDClassName.c_str(), GroupIDCtorSignature.c_str(),
                                                                   dataResponse.groupID, GroupID);
    jobject SceneID;
    std::string SceneIDClassName     = "java/lang/Integer";
    std::string SceneIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(SceneIDClassName.c_str(), SceneIDCtorSignature.c_str(),
                                                                  dataResponse.sceneID, SceneID);

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, GroupID, SceneID);
}
CHIPScenesClusterRemoveAllScenesResponseCallback::CHIPScenesClusterRemoveAllScenesResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPScenesClusterRemoveAllScenesResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPScenesClusterRemoveAllScenesResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Scenes::Commands::RemoveAllScenesResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPScenesClusterRemoveAllScenesResponseCallback, void (*)(CHIPScenesClusterRemoveAllScenesResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPScenesClusterRemoveAllScenesResponseCallback *>(context),
                    chip::Platform::Delete<CHIPScenesClusterRemoveAllScenesResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/lang/Integer;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject GroupID;
    std::string GroupIDClassName     = "java/lang/Integer";
    std::string GroupIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIDClassName.c_str(), GroupIDCtorSignature.c_str(),
                                                                   dataResponse.groupID, GroupID);

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, GroupID);
}
CHIPScenesClusterStoreSceneResponseCallback::CHIPScenesClusterStoreSceneResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPScenesClusterStoreSceneResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPScenesClusterStoreSceneResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Scenes::Commands::StoreSceneResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPScenesClusterStoreSceneResponseCallback, void (*)(CHIPScenesClusterStoreSceneResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPScenesClusterStoreSceneResponseCallback *>(context),
                    chip::Platform::Delete<CHIPScenesClusterStoreSceneResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject GroupID;
    std::string GroupIDClassName     = "java/lang/Integer";
    std::string GroupIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIDClassName.c_str(), GroupIDCtorSignature.c_str(),
                                                                   dataResponse.groupID, GroupID);
    jobject SceneID;
    std::string SceneIDClassName     = "java/lang/Integer";
    std::string SceneIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(SceneIDClassName.c_str(), SceneIDCtorSignature.c_str(),
                                                                  dataResponse.sceneID, SceneID);

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, GroupID, SceneID);
}
CHIPScenesClusterGetSceneMembershipResponseCallback::CHIPScenesClusterGetSceneMembershipResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPScenesClusterGetSceneMembershipResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPScenesClusterGetSceneMembershipResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Scenes::Commands::GetSceneMembershipResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPScenesClusterGetSceneMembershipResponseCallback,
                    void (*)(CHIPScenesClusterGetSceneMembershipResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPScenesClusterGetSceneMembershipResponseCallback *>(context),
                    chip::Platform::Delete<CHIPScenesClusterGetSceneMembershipResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/Optional;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject Capacity;
    if (dataResponse.capacity.IsNull())
    {
        Capacity = nullptr;
    }
    else
    {
        std::string CapacityClassName     = "java/lang/Integer";
        std::string CapacityCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(CapacityClassName.c_str(), CapacityCtorSignature.c_str(),
                                                                      dataResponse.capacity.Value(), Capacity);
    }
    jobject GroupID;
    std::string GroupIDClassName     = "java/lang/Integer";
    std::string GroupIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIDClassName.c_str(), GroupIDCtorSignature.c_str(),
                                                                   dataResponse.groupID, GroupID);
    jobject SceneList;
    if (!dataResponse.sceneList.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, SceneList);
    }
    else
    {
        jobject SceneListInsideOptional;
        chip::JniReferences::GetInstance().CreateArrayList(SceneListInsideOptional);

        auto iter_SceneListInsideOptional_1 = dataResponse.sceneList.Value().begin();
        while (iter_SceneListInsideOptional_1.Next())
        {
            auto & entry_1 = iter_SceneListInsideOptional_1.GetValue();
            jobject newElement_1;
            std::string newElement_1ClassName     = "java/lang/Integer";
            std::string newElement_1CtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_1ClassName.c_str(),
                                                                          newElement_1CtorSignature.c_str(), entry_1, newElement_1);
            chip::JniReferences::GetInstance().AddToList(SceneListInsideOptional, newElement_1);
        }
        chip::JniReferences::GetInstance().CreateOptional(SceneListInsideOptional, SceneList);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, Capacity, GroupID, SceneList);
}
CHIPScenesClusterEnhancedAddSceneResponseCallback::CHIPScenesClusterEnhancedAddSceneResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPScenesClusterEnhancedAddSceneResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPScenesClusterEnhancedAddSceneResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Scenes::Commands::EnhancedAddSceneResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPScenesClusterEnhancedAddSceneResponseCallback,
                    void (*)(CHIPScenesClusterEnhancedAddSceneResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPScenesClusterEnhancedAddSceneResponseCallback *>(context),
                    chip::Platform::Delete<CHIPScenesClusterEnhancedAddSceneResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject GroupID;
    std::string GroupIDClassName     = "java/lang/Integer";
    std::string GroupIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIDClassName.c_str(), GroupIDCtorSignature.c_str(),
                                                                   dataResponse.groupID, GroupID);
    jobject SceneID;
    std::string SceneIDClassName     = "java/lang/Integer";
    std::string SceneIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(SceneIDClassName.c_str(), SceneIDCtorSignature.c_str(),
                                                                  dataResponse.sceneID, SceneID);

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, GroupID, SceneID);
}
CHIPScenesClusterEnhancedViewSceneResponseCallback::CHIPScenesClusterEnhancedViewSceneResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPScenesClusterEnhancedViewSceneResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPScenesClusterEnhancedViewSceneResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Scenes::Commands::EnhancedViewSceneResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPScenesClusterEnhancedViewSceneResponseCallback,
                    void (*)(CHIPScenesClusterEnhancedViewSceneResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPScenesClusterEnhancedViewSceneResponseCallback *>(context),
                    chip::Platform::Delete<CHIPScenesClusterEnhancedViewSceneResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess",
        "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject GroupID;
    std::string GroupIDClassName     = "java/lang/Integer";
    std::string GroupIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIDClassName.c_str(), GroupIDCtorSignature.c_str(),
                                                                   dataResponse.groupID, GroupID);
    jobject SceneID;
    std::string SceneIDClassName     = "java/lang/Integer";
    std::string SceneIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(SceneIDClassName.c_str(), SceneIDCtorSignature.c_str(),
                                                                  dataResponse.sceneID, SceneID);
    jobject TransitionTime;
    if (!dataResponse.transitionTime.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, TransitionTime);
    }
    else
    {
        jobject TransitionTimeInsideOptional;
        std::string TransitionTimeInsideOptionalClassName     = "java/lang/Integer";
        std::string TransitionTimeInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            TransitionTimeInsideOptionalClassName.c_str(), TransitionTimeInsideOptionalCtorSignature.c_str(),
            dataResponse.transitionTime.Value(), TransitionTimeInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(TransitionTimeInsideOptional, TransitionTime);
    }
    jobject SceneName;
    if (!dataResponse.sceneName.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, SceneName);
    }
    else
    {
        jobject SceneNameInsideOptional;
        LogErrorOnFailure(
            chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.sceneName.Value(), SceneNameInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(SceneNameInsideOptional, SceneName);
    }
    jobject ExtensionFieldSets;
    if (!dataResponse.extensionFieldSets.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, ExtensionFieldSets);
    }
    else
    {
        jobject ExtensionFieldSetsInsideOptional;
        chip::JniReferences::GetInstance().CreateArrayList(ExtensionFieldSetsInsideOptional);

        auto iter_ExtensionFieldSetsInsideOptional_1 = dataResponse.extensionFieldSets.Value().begin();
        while (iter_ExtensionFieldSetsInsideOptional_1.Next())
        {
            auto & entry_1 = iter_ExtensionFieldSetsInsideOptional_1.GetValue();
            jobject newElement_1;
            jobject newElement_1_clusterID;
            std::string newElement_1_clusterIDClassName     = "java/lang/Long";
            std::string newElement_1_clusterIDCtorSignature = "(J)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_1_clusterIDClassName.c_str(),
                                                                           newElement_1_clusterIDCtorSignature.c_str(),
                                                                           entry_1.clusterID, newElement_1_clusterID);
            jobject newElement_1_attributeValueList;
            chip::JniReferences::GetInstance().CreateArrayList(newElement_1_attributeValueList);

            auto iter_newElement_1_attributeValueList_3 = entry_1.attributeValueList.begin();
            while (iter_newElement_1_attributeValueList_3.Next())
            {
                auto & entry_3 = iter_newElement_1_attributeValueList_3.GetValue();
                jobject newElement_3;
                jobject newElement_3_attributeID;
                if (!entry_3.attributeID.HasValue())
                {
                    chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_3_attributeID);
                }
                else
                {
                    jobject newElement_3_attributeIDInsideOptional;
                    std::string newElement_3_attributeIDInsideOptionalClassName     = "java/lang/Long";
                    std::string newElement_3_attributeIDInsideOptionalCtorSignature = "(J)V";
                    chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
                        newElement_3_attributeIDInsideOptionalClassName.c_str(),
                        newElement_3_attributeIDInsideOptionalCtorSignature.c_str(), entry_3.attributeID.Value(),
                        newElement_3_attributeIDInsideOptional);
                    chip::JniReferences::GetInstance().CreateOptional(newElement_3_attributeIDInsideOptional,
                                                                      newElement_3_attributeID);
                }
                jobject newElement_3_attributeValue;
                std::string newElement_3_attributeValueClassName     = "java/lang/Long";
                std::string newElement_3_attributeValueCtorSignature = "(J)V";
                chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(newElement_3_attributeValueClassName.c_str(),
                                                                               newElement_3_attributeValueCtorSignature.c_str(),
                                                                               entry_3.attributeValue, newElement_3_attributeValue);

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

                newElement_3 = env->NewObject(attributeValuePairStructClass_4, attributeValuePairStructCtor_4,
                                              newElement_3_attributeID, newElement_3_attributeValue);
                chip::JniReferences::GetInstance().AddToList(newElement_1_attributeValueList, newElement_3);
            }

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

            newElement_1 = env->NewObject(extensionFieldSetStructClass_2, extensionFieldSetStructCtor_2, newElement_1_clusterID,
                                          newElement_1_attributeValueList);
            chip::JniReferences::GetInstance().AddToList(ExtensionFieldSetsInsideOptional, newElement_1);
        }
        chip::JniReferences::GetInstance().CreateOptional(ExtensionFieldSetsInsideOptional, ExtensionFieldSets);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, GroupID, SceneID, TransitionTime, SceneName, ExtensionFieldSets);
}
CHIPScenesClusterCopySceneResponseCallback::CHIPScenesClusterCopySceneResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPScenesClusterCopySceneResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPScenesClusterCopySceneResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Scenes::Commands::CopySceneResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPScenesClusterCopySceneResponseCallback, void (*)(CHIPScenesClusterCopySceneResponseCallback *)> cppCallback(
        reinterpret_cast<CHIPScenesClusterCopySceneResponseCallback *>(context),
        chip::Platform::Delete<CHIPScenesClusterCopySceneResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  dataResponse.status, Status);
    jobject GroupIdentifierFrom;
    std::string GroupIdentifierFromClassName     = "java/lang/Integer";
    std::string GroupIdentifierFromCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(GroupIdentifierFromClassName.c_str(),
                                                                   GroupIdentifierFromCtorSignature.c_str(),
                                                                   dataResponse.groupIdentifierFrom, GroupIdentifierFrom);
    jobject SceneIdentifierFrom;
    std::string SceneIdentifierFromClassName     = "java/lang/Integer";
    std::string SceneIdentifierFromCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(SceneIdentifierFromClassName.c_str(),
                                                                  SceneIdentifierFromCtorSignature.c_str(),
                                                                  dataResponse.sceneIdentifierFrom, SceneIdentifierFrom);

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, GroupIdentifierFrom, SceneIdentifierFrom);
}
CHIPOtaSoftwareUpdateProviderClusterQueryImageResponseCallback::CHIPOtaSoftwareUpdateProviderClusterQueryImageResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPOtaSoftwareUpdateProviderClusterQueryImageResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPOtaSoftwareUpdateProviderClusterQueryImageResponseCallback::CallbackFn(
    void * context,
    const chip::app::Clusters::OtaSoftwareUpdateProvider::Commands::QueryImageResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPOtaSoftwareUpdateProviderClusterQueryImageResponseCallback,
                    void (*)(CHIPOtaSoftwareUpdateProviderClusterQueryImageResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPOtaSoftwareUpdateProviderClusterQueryImageResponseCallback *>(context),
                    chip::Platform::Delete<CHIPOtaSoftwareUpdateProviderClusterQueryImageResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess",
        "(Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/"
        "Optional;Ljava/util/Optional;Ljava/util/Optional;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);
    jobject DelayedActionTime;
    if (!dataResponse.delayedActionTime.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, DelayedActionTime);
    }
    else
    {
        jobject DelayedActionTimeInsideOptional;
        std::string DelayedActionTimeInsideOptionalClassName     = "java/lang/Long";
        std::string DelayedActionTimeInsideOptionalCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
            DelayedActionTimeInsideOptionalClassName.c_str(), DelayedActionTimeInsideOptionalCtorSignature.c_str(),
            dataResponse.delayedActionTime.Value(), DelayedActionTimeInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(DelayedActionTimeInsideOptional, DelayedActionTime);
    }
    jobject ImageURI;
    if (!dataResponse.imageURI.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, ImageURI);
    }
    else
    {
        jobject ImageURIInsideOptional;
        LogErrorOnFailure(
            chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.imageURI.Value(), ImageURIInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(ImageURIInsideOptional, ImageURI);
    }
    jobject SoftwareVersion;
    if (!dataResponse.softwareVersion.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, SoftwareVersion);
    }
    else
    {
        jobject SoftwareVersionInsideOptional;
        std::string SoftwareVersionInsideOptionalClassName     = "java/lang/Long";
        std::string SoftwareVersionInsideOptionalCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
            SoftwareVersionInsideOptionalClassName.c_str(), SoftwareVersionInsideOptionalCtorSignature.c_str(),
            dataResponse.softwareVersion.Value(), SoftwareVersionInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(SoftwareVersionInsideOptional, SoftwareVersion);
    }
    jobject SoftwareVersionString;
    if (!dataResponse.softwareVersionString.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, SoftwareVersionString);
    }
    else
    {
        jobject SoftwareVersionStringInsideOptional;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.softwareVersionString.Value(),
                                                                             SoftwareVersionStringInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(SoftwareVersionStringInsideOptional, SoftwareVersionString);
    }
    jobject UpdateToken;
    if (!dataResponse.updateToken.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, UpdateToken);
    }
    else
    {
        jobject UpdateTokenInsideOptional;
        jbyteArray UpdateTokenInsideOptionalByteArray =
            env->NewByteArray(static_cast<jsize>(dataResponse.updateToken.Value().size()));
        env->SetByteArrayRegion(UpdateTokenInsideOptionalByteArray, 0, static_cast<jsize>(dataResponse.updateToken.Value().size()),
                                reinterpret_cast<const jbyte *>(dataResponse.updateToken.Value().data()));
        UpdateTokenInsideOptional = UpdateTokenInsideOptionalByteArray;
        chip::JniReferences::GetInstance().CreateOptional(UpdateTokenInsideOptional, UpdateToken);
    }
    jobject UserConsentNeeded;
    if (!dataResponse.userConsentNeeded.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, UserConsentNeeded);
    }
    else
    {
        jobject UserConsentNeededInsideOptional;
        std::string UserConsentNeededInsideOptionalClassName     = "java/lang/Boolean";
        std::string UserConsentNeededInsideOptionalCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
            UserConsentNeededInsideOptionalClassName.c_str(), UserConsentNeededInsideOptionalCtorSignature.c_str(),
            dataResponse.userConsentNeeded.Value(), UserConsentNeededInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(UserConsentNeededInsideOptional, UserConsentNeeded);
    }
    jobject MetadataForRequestor;
    if (!dataResponse.metadataForRequestor.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, MetadataForRequestor);
    }
    else
    {
        jobject MetadataForRequestorInsideOptional;
        jbyteArray MetadataForRequestorInsideOptionalByteArray =
            env->NewByteArray(static_cast<jsize>(dataResponse.metadataForRequestor.Value().size()));
        env->SetByteArrayRegion(MetadataForRequestorInsideOptionalByteArray, 0,
                                static_cast<jsize>(dataResponse.metadataForRequestor.Value().size()),
                                reinterpret_cast<const jbyte *>(dataResponse.metadataForRequestor.Value().data()));
        MetadataForRequestorInsideOptional = MetadataForRequestorInsideOptionalByteArray;
        chip::JniReferences::GetInstance().CreateOptional(MetadataForRequestorInsideOptional, MetadataForRequestor);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, DelayedActionTime, ImageURI, SoftwareVersion, SoftwareVersionString,
                        UpdateToken, UserConsentNeeded, MetadataForRequestor);
}
CHIPOtaSoftwareUpdateProviderClusterApplyUpdateResponseCallback::CHIPOtaSoftwareUpdateProviderClusterApplyUpdateResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPOtaSoftwareUpdateProviderClusterApplyUpdateResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPOtaSoftwareUpdateProviderClusterApplyUpdateResponseCallback::CallbackFn(
    void * context,
    const chip::app::Clusters::OtaSoftwareUpdateProvider::Commands::ApplyUpdateResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPOtaSoftwareUpdateProviderClusterApplyUpdateResponseCallback,
                    void (*)(CHIPOtaSoftwareUpdateProviderClusterApplyUpdateResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPOtaSoftwareUpdateProviderClusterApplyUpdateResponseCallback *>(context),
                    chip::Platform::Delete<CHIPOtaSoftwareUpdateProviderClusterApplyUpdateResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/lang/Long;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Action;
    std::string ActionClassName     = "java/lang/Integer";
    std::string ActionCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(ActionClassName.c_str(), ActionCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.action), Action);
    jobject DelayedActionTime;
    std::string DelayedActionTimeClassName     = "java/lang/Long";
    std::string DelayedActionTimeCtorSignature = "(J)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(DelayedActionTimeClassName.c_str(),
                                                                   DelayedActionTimeCtorSignature.c_str(),
                                                                   dataResponse.delayedActionTime, DelayedActionTime);

    env->CallVoidMethod(javaCallbackRef, javaMethod, Action, DelayedActionTime);
}
CHIPGeneralCommissioningClusterArmFailSafeResponseCallback::CHIPGeneralCommissioningClusterArmFailSafeResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPGeneralCommissioningClusterArmFailSafeResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPGeneralCommissioningClusterArmFailSafeResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPGeneralCommissioningClusterArmFailSafeResponseCallback,
                    void (*)(CHIPGeneralCommissioningClusterArmFailSafeResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPGeneralCommissioningClusterArmFailSafeResponseCallback *>(context),
                    chip::Platform::Delete<CHIPGeneralCommissioningClusterArmFailSafeResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/lang/String;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject ErrorCode;
    std::string ErrorCodeClassName     = "java/lang/Integer";
    std::string ErrorCodeCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(ErrorCodeClassName.c_str(), ErrorCodeCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.errorCode), ErrorCode);
    jobject DebugText;
    LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.debugText, DebugText));

    env->CallVoidMethod(javaCallbackRef, javaMethod, ErrorCode, DebugText);
}
CHIPGeneralCommissioningClusterSetRegulatoryConfigResponseCallback::
    CHIPGeneralCommissioningClusterSetRegulatoryConfigResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPGeneralCommissioningClusterSetRegulatoryConfigResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPGeneralCommissioningClusterSetRegulatoryConfigResponseCallback::CallbackFn(
    void * context,
    const chip::app::Clusters::GeneralCommissioning::Commands::SetRegulatoryConfigResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPGeneralCommissioningClusterSetRegulatoryConfigResponseCallback,
                    void (*)(CHIPGeneralCommissioningClusterSetRegulatoryConfigResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPGeneralCommissioningClusterSetRegulatoryConfigResponseCallback *>(context),
                    chip::Platform::Delete<CHIPGeneralCommissioningClusterSetRegulatoryConfigResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/lang/String;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject ErrorCode;
    std::string ErrorCodeClassName     = "java/lang/Integer";
    std::string ErrorCodeCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(ErrorCodeClassName.c_str(), ErrorCodeCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.errorCode), ErrorCode);
    jobject DebugText;
    LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.debugText, DebugText));

    env->CallVoidMethod(javaCallbackRef, javaMethod, ErrorCode, DebugText);
}
CHIPGeneralCommissioningClusterCommissioningCompleteResponseCallback::
    CHIPGeneralCommissioningClusterCommissioningCompleteResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPGeneralCommissioningClusterCommissioningCompleteResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPGeneralCommissioningClusterCommissioningCompleteResponseCallback::CallbackFn(
    void * context,
    const chip::app::Clusters::GeneralCommissioning::Commands::CommissioningCompleteResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPGeneralCommissioningClusterCommissioningCompleteResponseCallback,
                    void (*)(CHIPGeneralCommissioningClusterCommissioningCompleteResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPGeneralCommissioningClusterCommissioningCompleteResponseCallback *>(context),
                    chip::Platform::Delete<CHIPGeneralCommissioningClusterCommissioningCompleteResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/lang/String;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject ErrorCode;
    std::string ErrorCodeClassName     = "java/lang/Integer";
    std::string ErrorCodeCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(ErrorCodeClassName.c_str(), ErrorCodeCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.errorCode), ErrorCode);
    jobject DebugText;
    LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.debugText, DebugText));

    env->CallVoidMethod(javaCallbackRef, javaMethod, ErrorCode, DebugText);
}
CHIPNetworkCommissioningClusterScanNetworksResponseCallback::CHIPNetworkCommissioningClusterScanNetworksResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPNetworkCommissioningClusterScanNetworksResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPNetworkCommissioningClusterScanNetworksResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPNetworkCommissioningClusterScanNetworksResponseCallback,
                    void (*)(CHIPNetworkCommissioningClusterScanNetworksResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPNetworkCommissioningClusterScanNetworksResponseCallback *>(context),
                    chip::Platform::Delete<CHIPNetworkCommissioningClusterScanNetworksResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject NetworkingStatus;
    std::string NetworkingStatusClassName     = "java/lang/Integer";
    std::string NetworkingStatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
        NetworkingStatusClassName.c_str(), NetworkingStatusCtorSignature.c_str(),
        static_cast<uint8_t>(dataResponse.networkingStatus), NetworkingStatus);
    jobject DebugText;
    if (!dataResponse.debugText.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, DebugText);
    }
    else
    {
        jobject DebugTextInsideOptional;
        LogErrorOnFailure(
            chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.debugText.Value(), DebugTextInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(DebugTextInsideOptional, DebugText);
    }
    jobject WiFiScanResults;
    if (!dataResponse.wiFiScanResults.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, WiFiScanResults);
    }
    else
    {
        jobject WiFiScanResultsInsideOptional;
        chip::JniReferences::GetInstance().CreateArrayList(WiFiScanResultsInsideOptional);

        auto iter_WiFiScanResultsInsideOptional_1 = dataResponse.wiFiScanResults.Value().begin();
        while (iter_WiFiScanResultsInsideOptional_1.Next())
        {
            auto & entry_1 = iter_WiFiScanResultsInsideOptional_1.GetValue();
            jobject newElement_1;
            jobject newElement_1_security;
            std::string newElement_1_securityClassName     = "java/lang/Integer";
            std::string newElement_1_securityCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_1_securityClassName.c_str(),
                                                                          newElement_1_securityCtorSignature.c_str(),
                                                                          entry_1.security.Raw(), newElement_1_security);
            jobject newElement_1_ssid;
            jbyteArray newElement_1_ssidByteArray = env->NewByteArray(static_cast<jsize>(entry_1.ssid.size()));
            env->SetByteArrayRegion(newElement_1_ssidByteArray, 0, static_cast<jsize>(entry_1.ssid.size()),
                                    reinterpret_cast<const jbyte *>(entry_1.ssid.data()));
            newElement_1_ssid = newElement_1_ssidByteArray;
            jobject newElement_1_bssid;
            jbyteArray newElement_1_bssidByteArray = env->NewByteArray(static_cast<jsize>(entry_1.bssid.size()));
            env->SetByteArrayRegion(newElement_1_bssidByteArray, 0, static_cast<jsize>(entry_1.bssid.size()),
                                    reinterpret_cast<const jbyte *>(entry_1.bssid.data()));
            newElement_1_bssid = newElement_1_bssidByteArray;
            jobject newElement_1_channel;
            std::string newElement_1_channelClassName     = "java/lang/Integer";
            std::string newElement_1_channelCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_1_channelClassName.c_str(),
                                                                           newElement_1_channelCtorSignature.c_str(),
                                                                           entry_1.channel, newElement_1_channel);
            jobject newElement_1_wiFiBand;
            std::string newElement_1_wiFiBandClassName     = "java/lang/Integer";
            std::string newElement_1_wiFiBandCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_1_wiFiBandClassName.c_str(), newElement_1_wiFiBandCtorSignature.c_str(),
                static_cast<uint8_t>(entry_1.wiFiBand), newElement_1_wiFiBand);
            jobject newElement_1_rssi;
            std::string newElement_1_rssiClassName     = "java/lang/Integer";
            std::string newElement_1_rssiCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<int8_t>(
                newElement_1_rssiClassName.c_str(), newElement_1_rssiCtorSignature.c_str(), entry_1.rssi, newElement_1_rssi);

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

            newElement_1 = env->NewObject(wiFiInterfaceScanResultStructClass_2, wiFiInterfaceScanResultStructCtor_2,
                                          newElement_1_security, newElement_1_ssid, newElement_1_bssid, newElement_1_channel,
                                          newElement_1_wiFiBand, newElement_1_rssi);
            chip::JniReferences::GetInstance().AddToList(WiFiScanResultsInsideOptional, newElement_1);
        }
        chip::JniReferences::GetInstance().CreateOptional(WiFiScanResultsInsideOptional, WiFiScanResults);
    }
    jobject ThreadScanResults;
    if (!dataResponse.threadScanResults.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, ThreadScanResults);
    }
    else
    {
        jobject ThreadScanResultsInsideOptional;
        chip::JniReferences::GetInstance().CreateArrayList(ThreadScanResultsInsideOptional);

        auto iter_ThreadScanResultsInsideOptional_1 = dataResponse.threadScanResults.Value().begin();
        while (iter_ThreadScanResultsInsideOptional_1.Next())
        {
            auto & entry_1 = iter_ThreadScanResultsInsideOptional_1.GetValue();
            jobject newElement_1;
            jobject newElement_1_panId;
            std::string newElement_1_panIdClassName     = "java/lang/Integer";
            std::string newElement_1_panIdCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
                newElement_1_panIdClassName.c_str(), newElement_1_panIdCtorSignature.c_str(), entry_1.panId, newElement_1_panId);
            jobject newElement_1_extendedPanId;
            std::string newElement_1_extendedPanIdClassName     = "java/lang/Long";
            std::string newElement_1_extendedPanIdCtorSignature = "(J)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(newElement_1_extendedPanIdClassName.c_str(),
                                                                           newElement_1_extendedPanIdCtorSignature.c_str(),
                                                                           entry_1.extendedPanId, newElement_1_extendedPanId);
            jobject newElement_1_networkName;
            LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_1.networkName, newElement_1_networkName));
            jobject newElement_1_channel;
            std::string newElement_1_channelClassName     = "java/lang/Integer";
            std::string newElement_1_channelCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_1_channelClassName.c_str(),
                                                                           newElement_1_channelCtorSignature.c_str(),
                                                                           entry_1.channel, newElement_1_channel);
            jobject newElement_1_version;
            std::string newElement_1_versionClassName     = "java/lang/Integer";
            std::string newElement_1_versionCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_1_versionClassName.c_str(),
                                                                          newElement_1_versionCtorSignature.c_str(),
                                                                          entry_1.version, newElement_1_version);
            jobject newElement_1_extendedAddress;
            jbyteArray newElement_1_extendedAddressByteArray =
                env->NewByteArray(static_cast<jsize>(entry_1.extendedAddress.size()));
            env->SetByteArrayRegion(newElement_1_extendedAddressByteArray, 0, static_cast<jsize>(entry_1.extendedAddress.size()),
                                    reinterpret_cast<const jbyte *>(entry_1.extendedAddress.data()));
            newElement_1_extendedAddress = newElement_1_extendedAddressByteArray;
            jobject newElement_1_rssi;
            std::string newElement_1_rssiClassName     = "java/lang/Integer";
            std::string newElement_1_rssiCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<int8_t>(
                newElement_1_rssiClassName.c_str(), newElement_1_rssiCtorSignature.c_str(), entry_1.rssi, newElement_1_rssi);
            jobject newElement_1_lqi;
            std::string newElement_1_lqiClassName     = "java/lang/Integer";
            std::string newElement_1_lqiCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_1_lqiClassName.c_str(), newElement_1_lqiCtorSignature.c_str(), entry_1.lqi, newElement_1_lqi);

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

            newElement_1 =
                env->NewObject(threadInterfaceScanResultStructClass_2, threadInterfaceScanResultStructCtor_2, newElement_1_panId,
                               newElement_1_extendedPanId, newElement_1_networkName, newElement_1_channel, newElement_1_version,
                               newElement_1_extendedAddress, newElement_1_rssi, newElement_1_lqi);
            chip::JniReferences::GetInstance().AddToList(ThreadScanResultsInsideOptional, newElement_1);
        }
        chip::JniReferences::GetInstance().CreateOptional(ThreadScanResultsInsideOptional, ThreadScanResults);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, NetworkingStatus, DebugText, WiFiScanResults, ThreadScanResults);
}
CHIPNetworkCommissioningClusterNetworkConfigResponseCallback::CHIPNetworkCommissioningClusterNetworkConfigResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPNetworkCommissioningClusterNetworkConfigResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPNetworkCommissioningClusterNetworkConfigResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::NetworkCommissioning::Commands::NetworkConfigResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPNetworkCommissioningClusterNetworkConfigResponseCallback,
                    void (*)(CHIPNetworkCommissioningClusterNetworkConfigResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPNetworkCommissioningClusterNetworkConfigResponseCallback *>(context),
                    chip::Platform::Delete<CHIPNetworkCommissioningClusterNetworkConfigResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject NetworkingStatus;
    std::string NetworkingStatusClassName     = "java/lang/Integer";
    std::string NetworkingStatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
        NetworkingStatusClassName.c_str(), NetworkingStatusCtorSignature.c_str(),
        static_cast<uint8_t>(dataResponse.networkingStatus), NetworkingStatus);
    jobject DebugText;
    if (!dataResponse.debugText.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, DebugText);
    }
    else
    {
        jobject DebugTextInsideOptional;
        LogErrorOnFailure(
            chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.debugText.Value(), DebugTextInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(DebugTextInsideOptional, DebugText);
    }
    jobject NetworkIndex;
    if (!dataResponse.networkIndex.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NetworkIndex);
    }
    else
    {
        jobject NetworkIndexInsideOptional;
        std::string NetworkIndexInsideOptionalClassName     = "java/lang/Integer";
        std::string NetworkIndexInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            NetworkIndexInsideOptionalClassName.c_str(), NetworkIndexInsideOptionalCtorSignature.c_str(),
            dataResponse.networkIndex.Value(), NetworkIndexInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(NetworkIndexInsideOptional, NetworkIndex);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, NetworkingStatus, DebugText, NetworkIndex);
}
CHIPNetworkCommissioningClusterConnectNetworkResponseCallback::CHIPNetworkCommissioningClusterConnectNetworkResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPNetworkCommissioningClusterConnectNetworkResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPNetworkCommissioningClusterConnectNetworkResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::NetworkCommissioning::Commands::ConnectNetworkResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPNetworkCommissioningClusterConnectNetworkResponseCallback,
                    void (*)(CHIPNetworkCommissioningClusterConnectNetworkResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPNetworkCommissioningClusterConnectNetworkResponseCallback *>(context),
                    chip::Platform::Delete<CHIPNetworkCommissioningClusterConnectNetworkResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/lang/Integer;Ljava/util/Optional;Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject NetworkingStatus;
    std::string NetworkingStatusClassName     = "java/lang/Integer";
    std::string NetworkingStatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
        NetworkingStatusClassName.c_str(), NetworkingStatusCtorSignature.c_str(),
        static_cast<uint8_t>(dataResponse.networkingStatus), NetworkingStatus);
    jobject DebugText;
    if (!dataResponse.debugText.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, DebugText);
    }
    else
    {
        jobject DebugTextInsideOptional;
        LogErrorOnFailure(
            chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.debugText.Value(), DebugTextInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(DebugTextInsideOptional, DebugText);
    }
    jobject ErrorValue;
    if (dataResponse.errorValue.IsNull())
    {
        ErrorValue = nullptr;
    }
    else
    {
        std::string ErrorValueClassName     = "java/lang/Long";
        std::string ErrorValueCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<int32_t>(ErrorValueClassName.c_str(), ErrorValueCtorSignature.c_str(),
                                                                      dataResponse.errorValue.Value(), ErrorValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, NetworkingStatus, DebugText, ErrorValue);
}
CHIPDiagnosticLogsClusterRetrieveLogsResponseCallback::CHIPDiagnosticLogsClusterRetrieveLogsResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPDiagnosticLogsClusterRetrieveLogsResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPDiagnosticLogsClusterRetrieveLogsResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::DiagnosticLogs::Commands::RetrieveLogsResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPDiagnosticLogsClusterRetrieveLogsResponseCallback,
                    void (*)(CHIPDiagnosticLogsClusterRetrieveLogsResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPDiagnosticLogsClusterRetrieveLogsResponseCallback *>(context),
                    chip::Platform::Delete<CHIPDiagnosticLogsClusterRetrieveLogsResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/lang/Integer;[BLjava/util/Optional;Ljava/util/Optional;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);
    jobject LogContent;
    jbyteArray LogContentByteArray = env->NewByteArray(static_cast<jsize>(dataResponse.logContent.size()));
    env->SetByteArrayRegion(LogContentByteArray, 0, static_cast<jsize>(dataResponse.logContent.size()),
                            reinterpret_cast<const jbyte *>(dataResponse.logContent.data()));
    LogContent = LogContentByteArray;
    jobject UTCTimeStamp;
    if (!dataResponse.UTCTimeStamp.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, UTCTimeStamp);
    }
    else
    {
        jobject UTCTimeStampInsideOptional;
        std::string UTCTimeStampInsideOptionalClassName     = "java/lang/Long";
        std::string UTCTimeStampInsideOptionalCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(
            UTCTimeStampInsideOptionalClassName.c_str(), UTCTimeStampInsideOptionalCtorSignature.c_str(),
            dataResponse.UTCTimeStamp.Value(), UTCTimeStampInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(UTCTimeStampInsideOptional, UTCTimeStamp);
    }
    jobject TimeSinceBoot;
    if (!dataResponse.timeSinceBoot.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, TimeSinceBoot);
    }
    else
    {
        jobject TimeSinceBootInsideOptional;
        std::string TimeSinceBootInsideOptionalClassName     = "java/lang/Long";
        std::string TimeSinceBootInsideOptionalCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(
            TimeSinceBootInsideOptionalClassName.c_str(), TimeSinceBootInsideOptionalCtorSignature.c_str(),
            dataResponse.timeSinceBoot.Value(), TimeSinceBootInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(TimeSinceBootInsideOptional, TimeSinceBoot);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, LogContent, UTCTimeStamp, TimeSinceBoot);
}
CHIPTimeSynchronizationClusterSetTimeZoneResponseCallback::CHIPTimeSynchronizationClusterSetTimeZoneResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPTimeSynchronizationClusterSetTimeZoneResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPTimeSynchronizationClusterSetTimeZoneResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::TimeSynchronization::Commands::SetTimeZoneResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPTimeSynchronizationClusterSetTimeZoneResponseCallback,
                    void (*)(CHIPTimeSynchronizationClusterSetTimeZoneResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPTimeSynchronizationClusterSetTimeZoneResponseCallback *>(context),
                    chip::Platform::Delete<CHIPTimeSynchronizationClusterSetTimeZoneResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Boolean;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject DSTOffsetRequired;
    std::string DSTOffsetRequiredClassName     = "java/lang/Boolean";
    std::string DSTOffsetRequiredCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(DSTOffsetRequiredClassName.c_str(),
                                                               DSTOffsetRequiredCtorSignature.c_str(),
                                                               dataResponse.DSTOffsetRequired, DSTOffsetRequired);

    env->CallVoidMethod(javaCallbackRef, javaMethod, DSTOffsetRequired);
}
CHIPOperationalCredentialsClusterAttestationResponseCallback::CHIPOperationalCredentialsClusterAttestationResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPOperationalCredentialsClusterAttestationResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPOperationalCredentialsClusterAttestationResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::OperationalCredentials::Commands::AttestationResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPOperationalCredentialsClusterAttestationResponseCallback,
                    void (*)(CHIPOperationalCredentialsClusterAttestationResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPOperationalCredentialsClusterAttestationResponseCallback *>(context),
                    chip::Platform::Delete<CHIPOperationalCredentialsClusterAttestationResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "([B[B)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject AttestationElements;
    jbyteArray AttestationElementsByteArray = env->NewByteArray(static_cast<jsize>(dataResponse.attestationElements.size()));
    env->SetByteArrayRegion(AttestationElementsByteArray, 0, static_cast<jsize>(dataResponse.attestationElements.size()),
                            reinterpret_cast<const jbyte *>(dataResponse.attestationElements.data()));
    AttestationElements = AttestationElementsByteArray;
    jobject AttestationSignature;
    jbyteArray AttestationSignatureByteArray = env->NewByteArray(static_cast<jsize>(dataResponse.attestationSignature.size()));
    env->SetByteArrayRegion(AttestationSignatureByteArray, 0, static_cast<jsize>(dataResponse.attestationSignature.size()),
                            reinterpret_cast<const jbyte *>(dataResponse.attestationSignature.data()));
    AttestationSignature = AttestationSignatureByteArray;

    env->CallVoidMethod(javaCallbackRef, javaMethod, AttestationElements, AttestationSignature);
}
CHIPOperationalCredentialsClusterCertificateChainResponseCallback::
    CHIPOperationalCredentialsClusterCertificateChainResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPOperationalCredentialsClusterCertificateChainResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPOperationalCredentialsClusterCertificateChainResponseCallback::CallbackFn(
    void * context,
    const chip::app::Clusters::OperationalCredentials::Commands::CertificateChainResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPOperationalCredentialsClusterCertificateChainResponseCallback,
                    void (*)(CHIPOperationalCredentialsClusterCertificateChainResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPOperationalCredentialsClusterCertificateChainResponseCallback *>(context),
                    chip::Platform::Delete<CHIPOperationalCredentialsClusterCertificateChainResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "([B)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Certificate;
    jbyteArray CertificateByteArray = env->NewByteArray(static_cast<jsize>(dataResponse.certificate.size()));
    env->SetByteArrayRegion(CertificateByteArray, 0, static_cast<jsize>(dataResponse.certificate.size()),
                            reinterpret_cast<const jbyte *>(dataResponse.certificate.data()));
    Certificate = CertificateByteArray;

    env->CallVoidMethod(javaCallbackRef, javaMethod, Certificate);
}
CHIPOperationalCredentialsClusterCSRResponseCallback::CHIPOperationalCredentialsClusterCSRResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPOperationalCredentialsClusterCSRResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPOperationalCredentialsClusterCSRResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::OperationalCredentials::Commands::CSRResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPOperationalCredentialsClusterCSRResponseCallback,
                    void (*)(CHIPOperationalCredentialsClusterCSRResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPOperationalCredentialsClusterCSRResponseCallback *>(context),
                    chip::Platform::Delete<CHIPOperationalCredentialsClusterCSRResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "([B[B)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject NOCSRElements;
    jbyteArray NOCSRElementsByteArray = env->NewByteArray(static_cast<jsize>(dataResponse.NOCSRElements.size()));
    env->SetByteArrayRegion(NOCSRElementsByteArray, 0, static_cast<jsize>(dataResponse.NOCSRElements.size()),
                            reinterpret_cast<const jbyte *>(dataResponse.NOCSRElements.data()));
    NOCSRElements = NOCSRElementsByteArray;
    jobject AttestationSignature;
    jbyteArray AttestationSignatureByteArray = env->NewByteArray(static_cast<jsize>(dataResponse.attestationSignature.size()));
    env->SetByteArrayRegion(AttestationSignatureByteArray, 0, static_cast<jsize>(dataResponse.attestationSignature.size()),
                            reinterpret_cast<const jbyte *>(dataResponse.attestationSignature.data()));
    AttestationSignature = AttestationSignatureByteArray;

    env->CallVoidMethod(javaCallbackRef, javaMethod, NOCSRElements, AttestationSignature);
}
CHIPOperationalCredentialsClusterNOCResponseCallback::CHIPOperationalCredentialsClusterNOCResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPOperationalCredentialsClusterNOCResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPOperationalCredentialsClusterNOCResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::OperationalCredentials::Commands::NOCResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPOperationalCredentialsClusterNOCResponseCallback,
                    void (*)(CHIPOperationalCredentialsClusterNOCResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPOperationalCredentialsClusterNOCResponseCallback *>(context),
                    chip::Platform::Delete<CHIPOperationalCredentialsClusterNOCResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject StatusCode;
    std::string StatusCodeClassName     = "java/lang/Integer";
    std::string StatusCodeCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusCodeClassName.c_str(), StatusCodeCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.statusCode), StatusCode);
    jobject FabricIndex;
    if (!dataResponse.fabricIndex.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, FabricIndex);
    }
    else
    {
        jobject FabricIndexInsideOptional;
        std::string FabricIndexInsideOptionalClassName     = "java/lang/Integer";
        std::string FabricIndexInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(FabricIndexInsideOptionalClassName.c_str(),
                                                                      FabricIndexInsideOptionalCtorSignature.c_str(),
                                                                      dataResponse.fabricIndex.Value(), FabricIndexInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(FabricIndexInsideOptional, FabricIndex);
    }
    jobject DebugText;
    if (!dataResponse.debugText.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, DebugText);
    }
    else
    {
        jobject DebugTextInsideOptional;
        LogErrorOnFailure(
            chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.debugText.Value(), DebugTextInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(DebugTextInsideOptional, DebugText);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, StatusCode, FabricIndex, DebugText);
}
CHIPGroupKeyManagementClusterKeySetReadResponseCallback::CHIPGroupKeyManagementClusterKeySetReadResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPGroupKeyManagementClusterKeySetReadResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPGroupKeyManagementClusterKeySetReadResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::GroupKeyManagement::Commands::KeySetReadResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPGroupKeyManagementClusterKeySetReadResponseCallback,
                    void (*)(CHIPGroupKeyManagementClusterKeySetReadResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPGroupKeyManagementClusterKeySetReadResponseCallback *>(context),
                    chip::Platform::Delete<CHIPGroupKeyManagementClusterKeySetReadResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess", "(Lchip/devicecontroller/ChipStructs$GroupKeyManagementClusterGroupKeySetStruct;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject GroupKeySet;
    jobject GroupKeySet_groupKeySetID;
    std::string GroupKeySet_groupKeySetIDClassName     = "java/lang/Integer";
    std::string GroupKeySet_groupKeySetIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
        GroupKeySet_groupKeySetIDClassName.c_str(), GroupKeySet_groupKeySetIDCtorSignature.c_str(),
        dataResponse.groupKeySet.groupKeySetID, GroupKeySet_groupKeySetID);
    jobject GroupKeySet_groupKeySecurityPolicy;
    std::string GroupKeySet_groupKeySecurityPolicyClassName     = "java/lang/Integer";
    std::string GroupKeySet_groupKeySecurityPolicyCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
        GroupKeySet_groupKeySecurityPolicyClassName.c_str(), GroupKeySet_groupKeySecurityPolicyCtorSignature.c_str(),
        static_cast<uint8_t>(dataResponse.groupKeySet.groupKeySecurityPolicy), GroupKeySet_groupKeySecurityPolicy);
    jobject GroupKeySet_epochKey0;
    if (dataResponse.groupKeySet.epochKey0.IsNull())
    {
        GroupKeySet_epochKey0 = nullptr;
    }
    else
    {
        jbyteArray GroupKeySet_epochKey0ByteArray =
            env->NewByteArray(static_cast<jsize>(dataResponse.groupKeySet.epochKey0.Value().size()));
        env->SetByteArrayRegion(GroupKeySet_epochKey0ByteArray, 0,
                                static_cast<jsize>(dataResponse.groupKeySet.epochKey0.Value().size()),
                                reinterpret_cast<const jbyte *>(dataResponse.groupKeySet.epochKey0.Value().data()));
        GroupKeySet_epochKey0 = GroupKeySet_epochKey0ByteArray;
    }
    jobject GroupKeySet_epochStartTime0;
    if (dataResponse.groupKeySet.epochStartTime0.IsNull())
    {
        GroupKeySet_epochStartTime0 = nullptr;
    }
    else
    {
        std::string GroupKeySet_epochStartTime0ClassName     = "java/lang/Long";
        std::string GroupKeySet_epochStartTime0CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(
            GroupKeySet_epochStartTime0ClassName.c_str(), GroupKeySet_epochStartTime0CtorSignature.c_str(),
            dataResponse.groupKeySet.epochStartTime0.Value(), GroupKeySet_epochStartTime0);
    }
    jobject GroupKeySet_epochKey1;
    if (dataResponse.groupKeySet.epochKey1.IsNull())
    {
        GroupKeySet_epochKey1 = nullptr;
    }
    else
    {
        jbyteArray GroupKeySet_epochKey1ByteArray =
            env->NewByteArray(static_cast<jsize>(dataResponse.groupKeySet.epochKey1.Value().size()));
        env->SetByteArrayRegion(GroupKeySet_epochKey1ByteArray, 0,
                                static_cast<jsize>(dataResponse.groupKeySet.epochKey1.Value().size()),
                                reinterpret_cast<const jbyte *>(dataResponse.groupKeySet.epochKey1.Value().data()));
        GroupKeySet_epochKey1 = GroupKeySet_epochKey1ByteArray;
    }
    jobject GroupKeySet_epochStartTime1;
    if (dataResponse.groupKeySet.epochStartTime1.IsNull())
    {
        GroupKeySet_epochStartTime1 = nullptr;
    }
    else
    {
        std::string GroupKeySet_epochStartTime1ClassName     = "java/lang/Long";
        std::string GroupKeySet_epochStartTime1CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(
            GroupKeySet_epochStartTime1ClassName.c_str(), GroupKeySet_epochStartTime1CtorSignature.c_str(),
            dataResponse.groupKeySet.epochStartTime1.Value(), GroupKeySet_epochStartTime1);
    }
    jobject GroupKeySet_epochKey2;
    if (dataResponse.groupKeySet.epochKey2.IsNull())
    {
        GroupKeySet_epochKey2 = nullptr;
    }
    else
    {
        jbyteArray GroupKeySet_epochKey2ByteArray =
            env->NewByteArray(static_cast<jsize>(dataResponse.groupKeySet.epochKey2.Value().size()));
        env->SetByteArrayRegion(GroupKeySet_epochKey2ByteArray, 0,
                                static_cast<jsize>(dataResponse.groupKeySet.epochKey2.Value().size()),
                                reinterpret_cast<const jbyte *>(dataResponse.groupKeySet.epochKey2.Value().data()));
        GroupKeySet_epochKey2 = GroupKeySet_epochKey2ByteArray;
    }
    jobject GroupKeySet_epochStartTime2;
    if (dataResponse.groupKeySet.epochStartTime2.IsNull())
    {
        GroupKeySet_epochStartTime2 = nullptr;
    }
    else
    {
        std::string GroupKeySet_epochStartTime2ClassName     = "java/lang/Long";
        std::string GroupKeySet_epochStartTime2CtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(
            GroupKeySet_epochStartTime2ClassName.c_str(), GroupKeySet_epochStartTime2CtorSignature.c_str(),
            dataResponse.groupKeySet.epochStartTime2.Value(), GroupKeySet_epochStartTime2);
    }

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

    GroupKeySet =
        env->NewObject(groupKeySetStructStructClass_0, groupKeySetStructStructCtor_0, GroupKeySet_groupKeySetID,
                       GroupKeySet_groupKeySecurityPolicy, GroupKeySet_epochKey0, GroupKeySet_epochStartTime0,
                       GroupKeySet_epochKey1, GroupKeySet_epochStartTime1, GroupKeySet_epochKey2, GroupKeySet_epochStartTime2);

    env->CallVoidMethod(javaCallbackRef, javaMethod, GroupKeySet);
}
CHIPGroupKeyManagementClusterKeySetReadAllIndicesResponseCallback::
    CHIPGroupKeyManagementClusterKeySetReadAllIndicesResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPGroupKeyManagementClusterKeySetReadAllIndicesResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPGroupKeyManagementClusterKeySetReadAllIndicesResponseCallback::CallbackFn(
    void * context,
    const chip::app::Clusters::GroupKeyManagement::Commands::KeySetReadAllIndicesResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPGroupKeyManagementClusterKeySetReadAllIndicesResponseCallback,
                    void (*)(CHIPGroupKeyManagementClusterKeySetReadAllIndicesResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPGroupKeyManagementClusterKeySetReadAllIndicesResponseCallback *>(context),
                    chip::Platform::Delete<CHIPGroupKeyManagementClusterKeySetReadAllIndicesResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/ArrayList;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

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

    auto iter_GroupKeySetIDs_0 = dataResponse.groupKeySetIDs.begin();
    while (iter_GroupKeySetIDs_0.Next())
    {
        auto & entry_0 = iter_GroupKeySetIDs_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(GroupKeySetIDs, newElement_0);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, GroupKeySetIDs);
}
CHIPIcdManagementClusterRegisterClientResponseCallback::CHIPIcdManagementClusterRegisterClientResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPIcdManagementClusterRegisterClientResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPIcdManagementClusterRegisterClientResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::IcdManagement::Commands::RegisterClientResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPIcdManagementClusterRegisterClientResponseCallback,
                    void (*)(CHIPIcdManagementClusterRegisterClientResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPIcdManagementClusterRegisterClientResponseCallback *>(context),
                    chip::Platform::Delete<CHIPIcdManagementClusterRegisterClientResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject ICDCounter;
    std::string ICDCounterClassName     = "java/lang/Long";
    std::string ICDCounterCtorSignature = "(J)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(ICDCounterClassName.c_str(), ICDCounterCtorSignature.c_str(),
                                                                   dataResponse.ICDCounter, ICDCounter);

    env->CallVoidMethod(javaCallbackRef, javaMethod, ICDCounter);
}
CHIPOperationalStateClusterOperationalCommandResponseCallback::CHIPOperationalStateClusterOperationalCommandResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPOperationalStateClusterOperationalCommandResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPOperationalStateClusterOperationalCommandResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::OperationalState::Commands::OperationalCommandResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPOperationalStateClusterOperationalCommandResponseCallback,
                    void (*)(CHIPOperationalStateClusterOperationalCommandResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPOperationalStateClusterOperationalCommandResponseCallback *>(context),
                    chip::Platform::Delete<CHIPOperationalStateClusterOperationalCommandResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Lchip/devicecontroller/ChipStructs$OperationalStateClusterErrorStateStruct;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject CommandResponseState;
    jobject CommandResponseState_errorStateID;
    std::string CommandResponseState_errorStateIDClassName     = "java/lang/Integer";
    std::string CommandResponseState_errorStateIDCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
        CommandResponseState_errorStateIDClassName.c_str(), CommandResponseState_errorStateIDCtorSignature.c_str(),
        static_cast<uint8_t>(dataResponse.commandResponseState.errorStateID), CommandResponseState_errorStateID);
    jobject CommandResponseState_errorStateLabel;
    if (dataResponse.commandResponseState.errorStateLabel.IsNull())
    {
        CommandResponseState_errorStateLabel = nullptr;
    }
    else
    {
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(
            dataResponse.commandResponseState.errorStateLabel.Value(), CommandResponseState_errorStateLabel));
    }
    jobject CommandResponseState_errorStateDetails;
    if (!dataResponse.commandResponseState.errorStateDetails.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, CommandResponseState_errorStateDetails);
    }
    else
    {
        jobject CommandResponseState_errorStateDetailsInsideOptional;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(
            dataResponse.commandResponseState.errorStateDetails.Value(), CommandResponseState_errorStateDetailsInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(CommandResponseState_errorStateDetailsInsideOptional,
                                                          CommandResponseState_errorStateDetails);
    }

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

    CommandResponseState =
        env->NewObject(errorStateStructStructClass_0, errorStateStructStructCtor_0, CommandResponseState_errorStateID,
                       CommandResponseState_errorStateLabel, CommandResponseState_errorStateDetails);

    env->CallVoidMethod(javaCallbackRef, javaMethod, CommandResponseState);
}
CHIPDoorLockClusterGetWeekDayScheduleResponseCallback::CHIPDoorLockClusterGetWeekDayScheduleResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPDoorLockClusterGetWeekDayScheduleResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPDoorLockClusterGetWeekDayScheduleResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::DoorLock::Commands::GetWeekDayScheduleResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPDoorLockClusterGetWeekDayScheduleResponseCallback,
                    void (*)(CHIPDoorLockClusterGetWeekDayScheduleResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPDoorLockClusterGetWeekDayScheduleResponseCallback *>(context),
                    chip::Platform::Delete<CHIPDoorLockClusterGetWeekDayScheduleResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess",
        "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/"
        "Optional;Ljava/util/Optional;Ljava/util/Optional;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject WeekDayIndex;
    std::string WeekDayIndexClassName     = "java/lang/Integer";
    std::string WeekDayIndexCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(WeekDayIndexClassName.c_str(), WeekDayIndexCtorSignature.c_str(),
                                                                  dataResponse.weekDayIndex, WeekDayIndex);
    jobject UserIndex;
    std::string UserIndexClassName     = "java/lang/Integer";
    std::string UserIndexCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(UserIndexClassName.c_str(), UserIndexCtorSignature.c_str(),
                                                                   dataResponse.userIndex, UserIndex);
    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);
    jobject DaysMask;
    if (!dataResponse.daysMask.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, DaysMask);
    }
    else
    {
        jobject DaysMaskInsideOptional;
        std::string DaysMaskInsideOptionalClassName     = "java/lang/Integer";
        std::string DaysMaskInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(DaysMaskInsideOptionalClassName.c_str(),
                                                                      DaysMaskInsideOptionalCtorSignature.c_str(),
                                                                      dataResponse.daysMask.Value().Raw(), DaysMaskInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(DaysMaskInsideOptional, DaysMask);
    }
    jobject StartHour;
    if (!dataResponse.startHour.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, StartHour);
    }
    else
    {
        jobject StartHourInsideOptional;
        std::string StartHourInsideOptionalClassName     = "java/lang/Integer";
        std::string StartHourInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StartHourInsideOptionalClassName.c_str(),
                                                                      StartHourInsideOptionalCtorSignature.c_str(),
                                                                      dataResponse.startHour.Value(), StartHourInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(StartHourInsideOptional, StartHour);
    }
    jobject StartMinute;
    if (!dataResponse.startMinute.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, StartMinute);
    }
    else
    {
        jobject StartMinuteInsideOptional;
        std::string StartMinuteInsideOptionalClassName     = "java/lang/Integer";
        std::string StartMinuteInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StartMinuteInsideOptionalClassName.c_str(),
                                                                      StartMinuteInsideOptionalCtorSignature.c_str(),
                                                                      dataResponse.startMinute.Value(), StartMinuteInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(StartMinuteInsideOptional, StartMinute);
    }
    jobject EndHour;
    if (!dataResponse.endHour.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, EndHour);
    }
    else
    {
        jobject EndHourInsideOptional;
        std::string EndHourInsideOptionalClassName     = "java/lang/Integer";
        std::string EndHourInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(EndHourInsideOptionalClassName.c_str(),
                                                                      EndHourInsideOptionalCtorSignature.c_str(),
                                                                      dataResponse.endHour.Value(), EndHourInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(EndHourInsideOptional, EndHour);
    }
    jobject EndMinute;
    if (!dataResponse.endMinute.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, EndMinute);
    }
    else
    {
        jobject EndMinuteInsideOptional;
        std::string EndMinuteInsideOptionalClassName     = "java/lang/Integer";
        std::string EndMinuteInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(EndMinuteInsideOptionalClassName.c_str(),
                                                                      EndMinuteInsideOptionalCtorSignature.c_str(),
                                                                      dataResponse.endMinute.Value(), EndMinuteInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(EndMinuteInsideOptional, EndMinute);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, WeekDayIndex, UserIndex, Status, DaysMask, StartHour, StartMinute, EndHour,
                        EndMinute);
}
CHIPDoorLockClusterGetYearDayScheduleResponseCallback::CHIPDoorLockClusterGetYearDayScheduleResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPDoorLockClusterGetYearDayScheduleResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPDoorLockClusterGetYearDayScheduleResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::DoorLock::Commands::GetYearDayScheduleResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPDoorLockClusterGetYearDayScheduleResponseCallback,
                    void (*)(CHIPDoorLockClusterGetYearDayScheduleResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPDoorLockClusterGetYearDayScheduleResponseCallback *>(context),
                    chip::Platform::Delete<CHIPDoorLockClusterGetYearDayScheduleResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess",
        "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject YearDayIndex;
    std::string YearDayIndexClassName     = "java/lang/Integer";
    std::string YearDayIndexCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(YearDayIndexClassName.c_str(), YearDayIndexCtorSignature.c_str(),
                                                                  dataResponse.yearDayIndex, YearDayIndex);
    jobject UserIndex;
    std::string UserIndexClassName     = "java/lang/Integer";
    std::string UserIndexCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(UserIndexClassName.c_str(), UserIndexCtorSignature.c_str(),
                                                                   dataResponse.userIndex, UserIndex);
    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);
    jobject LocalStartTime;
    if (!dataResponse.localStartTime.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, LocalStartTime);
    }
    else
    {
        jobject LocalStartTimeInsideOptional;
        std::string LocalStartTimeInsideOptionalClassName     = "java/lang/Long";
        std::string LocalStartTimeInsideOptionalCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
            LocalStartTimeInsideOptionalClassName.c_str(), LocalStartTimeInsideOptionalCtorSignature.c_str(),
            dataResponse.localStartTime.Value(), LocalStartTimeInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(LocalStartTimeInsideOptional, LocalStartTime);
    }
    jobject LocalEndTime;
    if (!dataResponse.localEndTime.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, LocalEndTime);
    }
    else
    {
        jobject LocalEndTimeInsideOptional;
        std::string LocalEndTimeInsideOptionalClassName     = "java/lang/Long";
        std::string LocalEndTimeInsideOptionalCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
            LocalEndTimeInsideOptionalClassName.c_str(), LocalEndTimeInsideOptionalCtorSignature.c_str(),
            dataResponse.localEndTime.Value(), LocalEndTimeInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(LocalEndTimeInsideOptional, LocalEndTime);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, YearDayIndex, UserIndex, Status, LocalStartTime, LocalEndTime);
}
CHIPDoorLockClusterGetHolidayScheduleResponseCallback::CHIPDoorLockClusterGetHolidayScheduleResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPDoorLockClusterGetHolidayScheduleResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPDoorLockClusterGetHolidayScheduleResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::DoorLock::Commands::GetHolidayScheduleResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPDoorLockClusterGetHolidayScheduleResponseCallback,
                    void (*)(CHIPDoorLockClusterGetHolidayScheduleResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPDoorLockClusterGetHolidayScheduleResponseCallback *>(context),
                    chip::Platform::Delete<CHIPDoorLockClusterGetHolidayScheduleResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess",
        "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject HolidayIndex;
    std::string HolidayIndexClassName     = "java/lang/Integer";
    std::string HolidayIndexCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(HolidayIndexClassName.c_str(), HolidayIndexCtorSignature.c_str(),
                                                                  dataResponse.holidayIndex, HolidayIndex);
    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);
    jobject LocalStartTime;
    if (!dataResponse.localStartTime.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, LocalStartTime);
    }
    else
    {
        jobject LocalStartTimeInsideOptional;
        std::string LocalStartTimeInsideOptionalClassName     = "java/lang/Long";
        std::string LocalStartTimeInsideOptionalCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
            LocalStartTimeInsideOptionalClassName.c_str(), LocalStartTimeInsideOptionalCtorSignature.c_str(),
            dataResponse.localStartTime.Value(), LocalStartTimeInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(LocalStartTimeInsideOptional, LocalStartTime);
    }
    jobject LocalEndTime;
    if (!dataResponse.localEndTime.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, LocalEndTime);
    }
    else
    {
        jobject LocalEndTimeInsideOptional;
        std::string LocalEndTimeInsideOptionalClassName     = "java/lang/Long";
        std::string LocalEndTimeInsideOptionalCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
            LocalEndTimeInsideOptionalClassName.c_str(), LocalEndTimeInsideOptionalCtorSignature.c_str(),
            dataResponse.localEndTime.Value(), LocalEndTimeInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(LocalEndTimeInsideOptional, LocalEndTime);
    }
    jobject OperatingMode;
    if (!dataResponse.operatingMode.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, OperatingMode);
    }
    else
    {
        jobject OperatingModeInsideOptional;
        std::string OperatingModeInsideOptionalClassName     = "java/lang/Integer";
        std::string OperatingModeInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            OperatingModeInsideOptionalClassName.c_str(), OperatingModeInsideOptionalCtorSignature.c_str(),
            static_cast<uint8_t>(dataResponse.operatingMode.Value()), OperatingModeInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(OperatingModeInsideOptional, OperatingMode);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, HolidayIndex, Status, LocalStartTime, LocalEndTime, OperatingMode);
}
CHIPDoorLockClusterGetUserResponseCallback::CHIPDoorLockClusterGetUserResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPDoorLockClusterGetUserResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPDoorLockClusterGetUserResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::DoorLock::Commands::GetUserResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPDoorLockClusterGetUserResponseCallback, void (*)(CHIPDoorLockClusterGetUserResponseCallback *)> cppCallback(
        reinterpret_cast<CHIPDoorLockClusterGetUserResponseCallback *>(context),
        chip::Platform::Delete<CHIPDoorLockClusterGetUserResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess",
        "(Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/"
        "ArrayList;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject UserIndex;
    std::string UserIndexClassName     = "java/lang/Integer";
    std::string UserIndexCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(UserIndexClassName.c_str(), UserIndexCtorSignature.c_str(),
                                                                   dataResponse.userIndex, UserIndex);
    jobject UserName;
    if (dataResponse.userName.IsNull())
    {
        UserName = nullptr;
    }
    else
    {
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.userName.Value(), UserName));
    }
    jobject UserUniqueID;
    if (dataResponse.userUniqueID.IsNull())
    {
        UserUniqueID = nullptr;
    }
    else
    {
        std::string UserUniqueIDClassName     = "java/lang/Long";
        std::string UserUniqueIDCtorSignature = "(J)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
            UserUniqueIDClassName.c_str(), UserUniqueIDCtorSignature.c_str(), dataResponse.userUniqueID.Value(), UserUniqueID);
    }
    jobject UserStatus;
    if (dataResponse.userStatus.IsNull())
    {
        UserStatus = nullptr;
    }
    else
    {
        std::string UserStatusClassName     = "java/lang/Integer";
        std::string UserStatusCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(UserStatusClassName.c_str(), UserStatusCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(dataResponse.userStatus.Value()),
                                                                      UserStatus);
    }
    jobject UserType;
    if (dataResponse.userType.IsNull())
    {
        UserType = nullptr;
    }
    else
    {
        std::string UserTypeClassName     = "java/lang/Integer";
        std::string UserTypeCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(UserTypeClassName.c_str(), UserTypeCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(dataResponse.userType.Value()),
                                                                      UserType);
    }
    jobject CredentialRule;
    if (dataResponse.credentialRule.IsNull())
    {
        CredentialRule = nullptr;
    }
    else
    {
        std::string CredentialRuleClassName     = "java/lang/Integer";
        std::string CredentialRuleCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            CredentialRuleClassName.c_str(), CredentialRuleCtorSignature.c_str(),
            static_cast<uint8_t>(dataResponse.credentialRule.Value()), CredentialRule);
    }
    jobject Credentials;
    if (dataResponse.credentials.IsNull())
    {
        Credentials = nullptr;
    }
    else
    {
        chip::JniReferences::GetInstance().CreateArrayList(Credentials);

        auto iter_Credentials_1 = dataResponse.credentials.Value().begin();
        while (iter_Credentials_1.Next())
        {
            auto & entry_1 = iter_Credentials_1.GetValue();
            jobject newElement_1;
            jobject newElement_1_credentialType;
            std::string newElement_1_credentialTypeClassName     = "java/lang/Integer";
            std::string newElement_1_credentialTypeCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_1_credentialTypeClassName.c_str(), newElement_1_credentialTypeCtorSignature.c_str(),
                static_cast<uint8_t>(entry_1.credentialType), newElement_1_credentialType);
            jobject newElement_1_credentialIndex;
            std::string newElement_1_credentialIndexClassName     = "java/lang/Integer";
            std::string newElement_1_credentialIndexCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_1_credentialIndexClassName.c_str(),
                                                                           newElement_1_credentialIndexCtorSignature.c_str(),
                                                                           entry_1.credentialIndex, newElement_1_credentialIndex);

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

            newElement_1 = env->NewObject(credentialStructStructClass_2, credentialStructStructCtor_2, newElement_1_credentialType,
                                          newElement_1_credentialIndex);
            chip::JniReferences::GetInstance().AddToList(Credentials, newElement_1);
        }
    }
    jobject CreatorFabricIndex;
    if (dataResponse.creatorFabricIndex.IsNull())
    {
        CreatorFabricIndex = nullptr;
    }
    else
    {
        std::string CreatorFabricIndexClassName     = "java/lang/Integer";
        std::string CreatorFabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(CreatorFabricIndexClassName.c_str(),
                                                                      CreatorFabricIndexCtorSignature.c_str(),
                                                                      dataResponse.creatorFabricIndex.Value(), CreatorFabricIndex);
    }
    jobject LastModifiedFabricIndex;
    if (dataResponse.lastModifiedFabricIndex.IsNull())
    {
        LastModifiedFabricIndex = nullptr;
    }
    else
    {
        std::string LastModifiedFabricIndexClassName     = "java/lang/Integer";
        std::string LastModifiedFabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            LastModifiedFabricIndexClassName.c_str(), LastModifiedFabricIndexCtorSignature.c_str(),
            dataResponse.lastModifiedFabricIndex.Value(), LastModifiedFabricIndex);
    }
    jobject NextUserIndex;
    if (dataResponse.nextUserIndex.IsNull())
    {
        NextUserIndex = nullptr;
    }
    else
    {
        std::string NextUserIndexClassName     = "java/lang/Integer";
        std::string NextUserIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            NextUserIndexClassName.c_str(), NextUserIndexCtorSignature.c_str(), dataResponse.nextUserIndex.Value(), NextUserIndex);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, UserIndex, UserName, UserUniqueID, UserStatus, UserType, CredentialRule,
                        Credentials, CreatorFabricIndex, LastModifiedFabricIndex, NextUserIndex);
}
CHIPDoorLockClusterSetCredentialResponseCallback::CHIPDoorLockClusterSetCredentialResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPDoorLockClusterSetCredentialResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPDoorLockClusterSetCredentialResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::DoorLock::Commands::SetCredentialResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPDoorLockClusterSetCredentialResponseCallback, void (*)(CHIPDoorLockClusterSetCredentialResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPDoorLockClusterSetCredentialResponseCallback *>(context),
                    chip::Platform::Delete<CHIPDoorLockClusterSetCredentialResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);
    jobject UserIndex;
    if (dataResponse.userIndex.IsNull())
    {
        UserIndex = nullptr;
    }
    else
    {
        std::string UserIndexClassName     = "java/lang/Integer";
        std::string UserIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(UserIndexClassName.c_str(), UserIndexCtorSignature.c_str(),
                                                                       dataResponse.userIndex.Value(), UserIndex);
    }
    jobject NextCredentialIndex;
    if (dataResponse.nextCredentialIndex.IsNull())
    {
        NextCredentialIndex = nullptr;
    }
    else
    {
        std::string NextCredentialIndexClassName     = "java/lang/Integer";
        std::string NextCredentialIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            NextCredentialIndexClassName.c_str(), NextCredentialIndexCtorSignature.c_str(),
            dataResponse.nextCredentialIndex.Value(), NextCredentialIndex);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, UserIndex, NextCredentialIndex);
}
CHIPDoorLockClusterGetCredentialStatusResponseCallback::CHIPDoorLockClusterGetCredentialStatusResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPDoorLockClusterGetCredentialStatusResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPDoorLockClusterGetCredentialStatusResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::DoorLock::Commands::GetCredentialStatusResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPDoorLockClusterGetCredentialStatusResponseCallback,
                    void (*)(CHIPDoorLockClusterGetCredentialStatusResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPDoorLockClusterGetCredentialStatusResponseCallback *>(context),
                    chip::Platform::Delete<CHIPDoorLockClusterGetCredentialStatusResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess",
        "(Ljava/lang/Boolean;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject CredentialExists;
    std::string CredentialExistsClassName     = "java/lang/Boolean";
    std::string CredentialExistsCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
        CredentialExistsClassName.c_str(), CredentialExistsCtorSignature.c_str(), dataResponse.credentialExists, CredentialExists);
    jobject UserIndex;
    if (dataResponse.userIndex.IsNull())
    {
        UserIndex = nullptr;
    }
    else
    {
        std::string UserIndexClassName     = "java/lang/Integer";
        std::string UserIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(UserIndexClassName.c_str(), UserIndexCtorSignature.c_str(),
                                                                       dataResponse.userIndex.Value(), UserIndex);
    }
    jobject CreatorFabricIndex;
    if (dataResponse.creatorFabricIndex.IsNull())
    {
        CreatorFabricIndex = nullptr;
    }
    else
    {
        std::string CreatorFabricIndexClassName     = "java/lang/Integer";
        std::string CreatorFabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(CreatorFabricIndexClassName.c_str(),
                                                                      CreatorFabricIndexCtorSignature.c_str(),
                                                                      dataResponse.creatorFabricIndex.Value(), CreatorFabricIndex);
    }
    jobject LastModifiedFabricIndex;
    if (dataResponse.lastModifiedFabricIndex.IsNull())
    {
        LastModifiedFabricIndex = nullptr;
    }
    else
    {
        std::string LastModifiedFabricIndexClassName     = "java/lang/Integer";
        std::string LastModifiedFabricIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            LastModifiedFabricIndexClassName.c_str(), LastModifiedFabricIndexCtorSignature.c_str(),
            dataResponse.lastModifiedFabricIndex.Value(), LastModifiedFabricIndex);
    }
    jobject NextCredentialIndex;
    if (dataResponse.nextCredentialIndex.IsNull())
    {
        NextCredentialIndex = nullptr;
    }
    else
    {
        std::string NextCredentialIndexClassName     = "java/lang/Integer";
        std::string NextCredentialIndexCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            NextCredentialIndexClassName.c_str(), NextCredentialIndexCtorSignature.c_str(),
            dataResponse.nextCredentialIndex.Value(), NextCredentialIndex);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, CredentialExists, UserIndex, CreatorFabricIndex, LastModifiedFabricIndex,
                        NextCredentialIndex);
}
CHIPThermostatClusterGetWeeklyScheduleResponseCallback::CHIPThermostatClusterGetWeeklyScheduleResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPThermostatClusterGetWeeklyScheduleResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPThermostatClusterGetWeeklyScheduleResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Thermostat::Commands::GetWeeklyScheduleResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPThermostatClusterGetWeeklyScheduleResponseCallback,
                    void (*)(CHIPThermostatClusterGetWeeklyScheduleResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPThermostatClusterGetWeeklyScheduleResponseCallback *>(context),
                    chip::Platform::Delete<CHIPThermostatClusterGetWeeklyScheduleResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/ArrayList;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject NumberOfTransitionsForSequence;
    std::string NumberOfTransitionsForSequenceClassName     = "java/lang/Integer";
    std::string NumberOfTransitionsForSequenceCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
        NumberOfTransitionsForSequenceClassName.c_str(), NumberOfTransitionsForSequenceCtorSignature.c_str(),
        dataResponse.numberOfTransitionsForSequence, NumberOfTransitionsForSequence);
    jobject DayOfWeekForSequence;
    std::string DayOfWeekForSequenceClassName     = "java/lang/Integer";
    std::string DayOfWeekForSequenceCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(DayOfWeekForSequenceClassName.c_str(),
                                                                  DayOfWeekForSequenceCtorSignature.c_str(),
                                                                  dataResponse.dayOfWeekForSequence.Raw(), DayOfWeekForSequence);
    jobject ModeForSequence;
    std::string ModeForSequenceClassName     = "java/lang/Integer";
    std::string ModeForSequenceCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(ModeForSequenceClassName.c_str(),
                                                                  ModeForSequenceCtorSignature.c_str(),
                                                                  dataResponse.modeForSequence.Raw(), ModeForSequence);
    jobject Transitions;
    chip::JniReferences::GetInstance().CreateArrayList(Transitions);

    auto iter_Transitions_0 = dataResponse.transitions.begin();
    while (iter_Transitions_0.Next())
    {
        auto & entry_0 = iter_Transitions_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_transitionTime;
        std::string newElement_0_transitionTimeClassName     = "java/lang/Integer";
        std::string newElement_0_transitionTimeCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(newElement_0_transitionTimeClassName.c_str(),
                                                                       newElement_0_transitionTimeCtorSignature.c_str(),
                                                                       entry_0.transitionTime, newElement_0_transitionTime);
        jobject newElement_0_heatSetpoint;
        if (entry_0.heatSetpoint.IsNull())
        {
            newElement_0_heatSetpoint = nullptr;
        }
        else
        {
            std::string newElement_0_heatSetpointClassName     = "java/lang/Integer";
            std::string newElement_0_heatSetpointCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(newElement_0_heatSetpointClassName.c_str(),
                                                                          newElement_0_heatSetpointCtorSignature.c_str(),
                                                                          entry_0.heatSetpoint.Value(), newElement_0_heatSetpoint);
        }
        jobject newElement_0_coolSetpoint;
        if (entry_0.coolSetpoint.IsNull())
        {
            newElement_0_coolSetpoint = nullptr;
        }
        else
        {
            std::string newElement_0_coolSetpointClassName     = "java/lang/Integer";
            std::string newElement_0_coolSetpointCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<int16_t>(newElement_0_coolSetpointClassName.c_str(),
                                                                          newElement_0_coolSetpointCtorSignature.c_str(),
                                                                          entry_0.coolSetpoint.Value(), newElement_0_coolSetpoint);
        }

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

        newElement_0 = env->NewObject(thermostatScheduleTransitionStructClass_1, thermostatScheduleTransitionStructCtor_1,
                                      newElement_0_transitionTime, newElement_0_heatSetpoint, newElement_0_coolSetpoint);
        chip::JniReferences::GetInstance().AddToList(Transitions, newElement_0);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, NumberOfTransitionsForSequence, DayOfWeekForSequence, ModeForSequence,
                        Transitions);
}
CHIPChannelClusterChangeChannelResponseCallback::CHIPChannelClusterChangeChannelResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPChannelClusterChangeChannelResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPChannelClusterChangeChannelResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::Channel::Commands::ChangeChannelResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPChannelClusterChangeChannelResponseCallback, void (*)(CHIPChannelClusterChangeChannelResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPChannelClusterChangeChannelResponseCallback *>(context),
                    chip::Platform::Delete<CHIPChannelClusterChangeChannelResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/util/Optional;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);
    jobject Data;
    if (!dataResponse.data.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, Data);
    }
    else
    {
        jobject DataInsideOptional;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.data.Value(), DataInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(DataInsideOptional, Data);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, Data);
}
CHIPTargetNavigatorClusterNavigateTargetResponseCallback::CHIPTargetNavigatorClusterNavigateTargetResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPTargetNavigatorClusterNavigateTargetResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPTargetNavigatorClusterNavigateTargetResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPTargetNavigatorClusterNavigateTargetResponseCallback,
                    void (*)(CHIPTargetNavigatorClusterNavigateTargetResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPTargetNavigatorClusterNavigateTargetResponseCallback *>(context),
                    chip::Platform::Delete<CHIPTargetNavigatorClusterNavigateTargetResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/util/Optional;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);
    jobject Data;
    if (!dataResponse.data.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, Data);
    }
    else
    {
        jobject DataInsideOptional;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.data.Value(), DataInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(DataInsideOptional, Data);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, Data);
}
CHIPMediaPlaybackClusterPlaybackResponseCallback::CHIPMediaPlaybackClusterPlaybackResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPMediaPlaybackClusterPlaybackResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPMediaPlaybackClusterPlaybackResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPMediaPlaybackClusterPlaybackResponseCallback, void (*)(CHIPMediaPlaybackClusterPlaybackResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPMediaPlaybackClusterPlaybackResponseCallback *>(context),
                    chip::Platform::Delete<CHIPMediaPlaybackClusterPlaybackResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/util/Optional;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);
    jobject Data;
    if (!dataResponse.data.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, Data);
    }
    else
    {
        jobject DataInsideOptional;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.data.Value(), DataInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(DataInsideOptional, Data);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, Data);
}
CHIPKeypadInputClusterSendKeyResponseCallback::CHIPKeypadInputClusterSendKeyResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPKeypadInputClusterSendKeyResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPKeypadInputClusterSendKeyResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::KeypadInput::Commands::SendKeyResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPKeypadInputClusterSendKeyResponseCallback, void (*)(CHIPKeypadInputClusterSendKeyResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPKeypadInputClusterSendKeyResponseCallback *>(context),
                    chip::Platform::Delete<CHIPKeypadInputClusterSendKeyResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status);
}
CHIPContentLauncherClusterLauncherResponseCallback::CHIPContentLauncherClusterLauncherResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPContentLauncherClusterLauncherResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPContentLauncherClusterLauncherResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::ContentLauncher::Commands::LauncherResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPContentLauncherClusterLauncherResponseCallback,
                    void (*)(CHIPContentLauncherClusterLauncherResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPContentLauncherClusterLauncherResponseCallback *>(context),
                    chip::Platform::Delete<CHIPContentLauncherClusterLauncherResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/util/Optional;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);
    jobject Data;
    if (!dataResponse.data.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, Data);
    }
    else
    {
        jobject DataInsideOptional;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.data.Value(), DataInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(DataInsideOptional, Data);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, Data);
}
CHIPApplicationLauncherClusterLauncherResponseCallback::CHIPApplicationLauncherClusterLauncherResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPApplicationLauncherClusterLauncherResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPApplicationLauncherClusterLauncherResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPApplicationLauncherClusterLauncherResponseCallback,
                    void (*)(CHIPApplicationLauncherClusterLauncherResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPApplicationLauncherClusterLauncherResponseCallback *>(context),
                    chip::Platform::Delete<CHIPApplicationLauncherClusterLauncherResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/util/Optional;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject Status;
    std::string StatusClassName     = "java/lang/Integer";
    std::string StatusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(StatusClassName.c_str(), StatusCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.status), Status);
    jobject Data;
    if (!dataResponse.data.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, Data);
    }
    else
    {
        jobject DataInsideOptional;
        jbyteArray DataInsideOptionalByteArray = env->NewByteArray(static_cast<jsize>(dataResponse.data.Value().size()));
        env->SetByteArrayRegion(DataInsideOptionalByteArray, 0, static_cast<jsize>(dataResponse.data.Value().size()),
                                reinterpret_cast<const jbyte *>(dataResponse.data.Value().data()));
        DataInsideOptional = DataInsideOptionalByteArray;
        chip::JniReferences::GetInstance().CreateOptional(DataInsideOptional, Data);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, Status, Data);
}
CHIPAccountLoginClusterGetSetupPINResponseCallback::CHIPAccountLoginClusterGetSetupPINResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPAccountLoginClusterGetSetupPINResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPAccountLoginClusterGetSetupPINResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::AccountLogin::Commands::GetSetupPINResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPAccountLoginClusterGetSetupPINResponseCallback,
                    void (*)(CHIPAccountLoginClusterGetSetupPINResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPAccountLoginClusterGetSetupPINResponseCallback *>(context),
                    chip::Platform::Delete<CHIPAccountLoginClusterGetSetupPINResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/String;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject SetupPIN;
    LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.setupPIN, SetupPIN));

    env->CallVoidMethod(javaCallbackRef, javaMethod, SetupPIN);
}
CHIPElectricalMeasurementClusterGetProfileInfoResponseCommandCallback::
    CHIPElectricalMeasurementClusterGetProfileInfoResponseCommandCallback(jobject javaCallback) :
    Callback::Callback<CHIPElectricalMeasurementClusterGetProfileInfoResponseCommandCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPElectricalMeasurementClusterGetProfileInfoResponseCommandCallback::CallbackFn(
    void * context,
    const chip::app::Clusters::ElectricalMeasurement::Commands::GetProfileInfoResponseCommand::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPElectricalMeasurementClusterGetProfileInfoResponseCommandCallback,
                    void (*)(CHIPElectricalMeasurementClusterGetProfileInfoResponseCommandCallback *)>
        cppCallback(reinterpret_cast<CHIPElectricalMeasurementClusterGetProfileInfoResponseCommandCallback *>(context),
                    chip::Platform::Delete<CHIPElectricalMeasurementClusterGetProfileInfoResponseCommandCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/ArrayList;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject profileCount;
    std::string profileCountClassName     = "java/lang/Integer";
    std::string profileCountCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(profileCountClassName.c_str(), profileCountCtorSignature.c_str(),
                                                                  dataResponse.profileCount, profileCount);
    jobject profileIntervalPeriod;
    std::string profileIntervalPeriodClassName     = "java/lang/Integer";
    std::string profileIntervalPeriodCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(profileIntervalPeriodClassName.c_str(),
                                                                  profileIntervalPeriodCtorSignature.c_str(),
                                                                  dataResponse.profileIntervalPeriod, profileIntervalPeriod);
    jobject maxNumberOfIntervals;
    std::string maxNumberOfIntervalsClassName     = "java/lang/Integer";
    std::string maxNumberOfIntervalsCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(maxNumberOfIntervalsClassName.c_str(),
                                                                  maxNumberOfIntervalsCtorSignature.c_str(),
                                                                  dataResponse.maxNumberOfIntervals, maxNumberOfIntervals);
    jobject listOfAttributes;
    chip::JniReferences::GetInstance().CreateArrayList(listOfAttributes);

    auto iter_listOfAttributes_0 = dataResponse.listOfAttributes.begin();
    while (iter_listOfAttributes_0.Next())
    {
        auto & entry_0 = iter_listOfAttributes_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(listOfAttributes, newElement_0);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, profileCount, profileIntervalPeriod, maxNumberOfIntervals, listOfAttributes);
}
CHIPElectricalMeasurementClusterGetMeasurementProfileResponseCommandCallback::
    CHIPElectricalMeasurementClusterGetMeasurementProfileResponseCommandCallback(jobject javaCallback) :
    Callback::Callback<CHIPElectricalMeasurementClusterGetMeasurementProfileResponseCommandCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPElectricalMeasurementClusterGetMeasurementProfileResponseCommandCallback::CallbackFn(
    void * context,
    const chip::app::Clusters::ElectricalMeasurement::Commands::GetMeasurementProfileResponseCommand::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPElectricalMeasurementClusterGetMeasurementProfileResponseCommandCallback,
                    void (*)(CHIPElectricalMeasurementClusterGetMeasurementProfileResponseCommandCallback *)>
        cppCallback(reinterpret_cast<CHIPElectricalMeasurementClusterGetMeasurementProfileResponseCommandCallback *>(context),
                    chip::Platform::Delete<CHIPElectricalMeasurementClusterGetMeasurementProfileResponseCommandCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess",
        "(Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/ArrayList;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject startTime;
    std::string startTimeClassName     = "java/lang/Long";
    std::string startTimeCtorSignature = "(J)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(startTimeClassName.c_str(), startTimeCtorSignature.c_str(),
                                                                   dataResponse.startTime, startTime);
    jobject status;
    std::string statusClassName     = "java/lang/Integer";
    std::string statusCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(statusClassName.c_str(), statusCtorSignature.c_str(),
                                                                  dataResponse.status, status);
    jobject profileIntervalPeriod;
    std::string profileIntervalPeriodClassName     = "java/lang/Integer";
    std::string profileIntervalPeriodCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(profileIntervalPeriodClassName.c_str(),
                                                                  profileIntervalPeriodCtorSignature.c_str(),
                                                                  dataResponse.profileIntervalPeriod, profileIntervalPeriod);
    jobject numberOfIntervalsDelivered;
    std::string numberOfIntervalsDeliveredClassName     = "java/lang/Integer";
    std::string numberOfIntervalsDeliveredCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
        numberOfIntervalsDeliveredClassName.c_str(), numberOfIntervalsDeliveredCtorSignature.c_str(),
        dataResponse.numberOfIntervalsDelivered, numberOfIntervalsDelivered);
    jobject attributeId;
    std::string attributeIdClassName     = "java/lang/Integer";
    std::string attributeIdCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(attributeIdClassName.c_str(), attributeIdCtorSignature.c_str(),
                                                                   dataResponse.attributeId, attributeId);
    jobject intervals;
    chip::JniReferences::GetInstance().CreateArrayList(intervals);

    auto iter_intervals_0 = dataResponse.intervals.begin();
    while (iter_intervals_0.Next())
    {
        auto & entry_0 = iter_intervals_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(intervals, newElement_0);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, startTime, status, profileIntervalPeriod, numberOfIntervalsDelivered,
                        attributeId, intervals);
}
CHIPUnitTestingClusterTestSpecificResponseCallback::CHIPUnitTestingClusterTestSpecificResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterTestSpecificResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterTestSpecificResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::UnitTesting::Commands::TestSpecificResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterTestSpecificResponseCallback,
                    void (*)(CHIPUnitTestingClusterTestSpecificResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterTestSpecificResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterTestSpecificResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject returnValue;
    std::string returnValueClassName     = "java/lang/Integer";
    std::string returnValueCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(returnValueClassName.c_str(), returnValueCtorSignature.c_str(),
                                                                  dataResponse.returnValue, returnValue);

    env->CallVoidMethod(javaCallbackRef, javaMethod, returnValue);
}
CHIPUnitTestingClusterTestAddArgumentsResponseCallback::CHIPUnitTestingClusterTestAddArgumentsResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterTestAddArgumentsResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterTestAddArgumentsResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::UnitTesting::Commands::TestAddArgumentsResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterTestAddArgumentsResponseCallback,
                    void (*)(CHIPUnitTestingClusterTestAddArgumentsResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterTestAddArgumentsResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterTestAddArgumentsResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject returnValue;
    std::string returnValueClassName     = "java/lang/Integer";
    std::string returnValueCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(returnValueClassName.c_str(), returnValueCtorSignature.c_str(),
                                                                  dataResponse.returnValue, returnValue);

    env->CallVoidMethod(javaCallbackRef, javaMethod, returnValue);
}
CHIPUnitTestingClusterTestSimpleArgumentResponseCallback::CHIPUnitTestingClusterTestSimpleArgumentResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterTestSimpleArgumentResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterTestSimpleArgumentResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::UnitTesting::Commands::TestSimpleArgumentResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterTestSimpleArgumentResponseCallback,
                    void (*)(CHIPUnitTestingClusterTestSimpleArgumentResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterTestSimpleArgumentResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterTestSimpleArgumentResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Boolean;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject returnValue;
    std::string returnValueClassName     = "java/lang/Boolean";
    std::string returnValueCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(returnValueClassName.c_str(), returnValueCtorSignature.c_str(),
                                                               dataResponse.returnValue, returnValue);

    env->CallVoidMethod(javaCallbackRef, javaMethod, returnValue);
}
CHIPUnitTestingClusterTestStructArrayArgumentResponseCallback::CHIPUnitTestingClusterTestStructArrayArgumentResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterTestStructArrayArgumentResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterTestStructArrayArgumentResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::UnitTesting::Commands::TestStructArrayArgumentResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterTestStructArrayArgumentResponseCallback,
                    void (*)(CHIPUnitTestingClusterTestStructArrayArgumentResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterTestStructArrayArgumentResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterTestStructArrayArgumentResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess",
                                                  "(Ljava/util/ArrayList;Ljava/util/ArrayList;Ljava/util/ArrayList;Ljava/util/"
                                                  "ArrayList;Ljava/lang/Integer;Ljava/lang/Boolean;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

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

    auto iter_arg1_0 = dataResponse.arg1.begin();
    while (iter_arg1_0.Next())
    {
        auto & entry_0 = iter_arg1_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_a;
        std::string newElement_0_aClassName     = "java/lang/Integer";
        std::string newElement_0_aCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_aClassName.c_str(), newElement_0_aCtorSignature.c_str(), entry_0.a, newElement_0_a);
        jobject newElement_0_b;
        std::string newElement_0_bClassName     = "java/lang/Boolean";
        std::string newElement_0_bCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(newElement_0_bClassName.c_str(),
                                                                   newElement_0_bCtorSignature.c_str(), entry_0.b, newElement_0_b);
        jobject newElement_0_c;
        jobject newElement_0_c_a;
        std::string newElement_0_c_aClassName     = "java/lang/Integer";
        std::string newElement_0_c_aCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_c_aClassName.c_str(), newElement_0_c_aCtorSignature.c_str(), entry_0.c.a, newElement_0_c_a);
        jobject newElement_0_c_b;
        std::string newElement_0_c_bClassName     = "java/lang/Boolean";
        std::string newElement_0_c_bCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
            newElement_0_c_bClassName.c_str(), newElement_0_c_bCtorSignature.c_str(), entry_0.c.b, newElement_0_c_b);
        jobject newElement_0_c_c;
        std::string newElement_0_c_cClassName     = "java/lang/Integer";
        std::string newElement_0_c_cCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_0_c_cClassName.c_str(),
                                                                      newElement_0_c_cCtorSignature.c_str(),
                                                                      static_cast<uint8_t>(entry_0.c.c), newElement_0_c_c);
        jobject newElement_0_c_d;
        jbyteArray newElement_0_c_dByteArray = env->NewByteArray(static_cast<jsize>(entry_0.c.d.size()));
        env->SetByteArrayRegion(newElement_0_c_dByteArray, 0, static_cast<jsize>(entry_0.c.d.size()),
                                reinterpret_cast<const jbyte *>(entry_0.c.d.data()));
        newElement_0_c_d = newElement_0_c_dByteArray;
        jobject newElement_0_c_e;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.c.e, newElement_0_c_e));
        jobject newElement_0_c_f;
        std::string newElement_0_c_fClassName     = "java/lang/Integer";
        std::string newElement_0_c_fCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_c_fClassName.c_str(), newElement_0_c_fCtorSignature.c_str(), entry_0.c.f.Raw(), newElement_0_c_f);
        jobject newElement_0_c_g;
        std::string newElement_0_c_gClassName     = "java/lang/Float";
        std::string newElement_0_c_gCtorSignature = "(F)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<float>(
            newElement_0_c_gClassName.c_str(), newElement_0_c_gCtorSignature.c_str(), entry_0.c.g, newElement_0_c_g);
        jobject newElement_0_c_h;
        std::string newElement_0_c_hClassName     = "java/lang/Double";
        std::string newElement_0_c_hCtorSignature = "(D)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<double>(
            newElement_0_c_hClassName.c_str(), newElement_0_c_hCtorSignature.c_str(), entry_0.c.h, newElement_0_c_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_c = env->NewObject(simpleStructStructClass_2, simpleStructStructCtor_2, newElement_0_c_a, newElement_0_c_b,
                                        newElement_0_c_c, newElement_0_c_d, newElement_0_c_e, newElement_0_c_f, newElement_0_c_g,
                                        newElement_0_c_h);
        jobject newElement_0_d;
        chip::JniReferences::GetInstance().CreateArrayList(newElement_0_d);

        auto iter_newElement_0_d_2 = entry_0.d.begin();
        while (iter_newElement_0_d_2.Next())
        {
            auto & entry_2 = iter_newElement_0_d_2.GetValue();
            jobject newElement_2;
            jobject newElement_2_a;
            std::string newElement_2_aClassName     = "java/lang/Integer";
            std::string newElement_2_aCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_2_aClassName.c_str(), newElement_2_aCtorSignature.c_str(), entry_2.a, newElement_2_a);
            jobject newElement_2_b;
            std::string newElement_2_bClassName     = "java/lang/Boolean";
            std::string newElement_2_bCtorSignature = "(Z)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
                newElement_2_bClassName.c_str(), newElement_2_bCtorSignature.c_str(), entry_2.b, newElement_2_b);
            jobject newElement_2_c;
            std::string newElement_2_cClassName     = "java/lang/Integer";
            std::string newElement_2_cCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(newElement_2_cClassName.c_str(),
                                                                          newElement_2_cCtorSignature.c_str(),
                                                                          static_cast<uint8_t>(entry_2.c), newElement_2_c);
            jobject newElement_2_d;
            jbyteArray newElement_2_dByteArray = env->NewByteArray(static_cast<jsize>(entry_2.d.size()));
            env->SetByteArrayRegion(newElement_2_dByteArray, 0, static_cast<jsize>(entry_2.d.size()),
                                    reinterpret_cast<const jbyte *>(entry_2.d.data()));
            newElement_2_d = newElement_2_dByteArray;
            jobject newElement_2_e;
            LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_2.e, newElement_2_e));
            jobject newElement_2_f;
            std::string newElement_2_fClassName     = "java/lang/Integer";
            std::string newElement_2_fCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_2_fClassName.c_str(), newElement_2_fCtorSignature.c_str(), entry_2.f.Raw(), newElement_2_f);
            jobject newElement_2_g;
            std::string newElement_2_gClassName     = "java/lang/Float";
            std::string newElement_2_gCtorSignature = "(F)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<float>(
                newElement_2_gClassName.c_str(), newElement_2_gCtorSignature.c_str(), entry_2.g, newElement_2_g);
            jobject newElement_2_h;
            std::string newElement_2_hClassName     = "java/lang/Double";
            std::string newElement_2_hCtorSignature = "(D)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<double>(
                newElement_2_hClassName.c_str(), newElement_2_hCtorSignature.c_str(), entry_2.h, newElement_2_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_2 =
                env->NewObject(simpleStructStructClass_3, simpleStructStructCtor_3, newElement_2_a, newElement_2_b, newElement_2_c,
                               newElement_2_d, newElement_2_e, newElement_2_f, newElement_2_g, newElement_2_h);
            chip::JniReferences::GetInstance().AddToList(newElement_0_d, newElement_2);
        }
        jobject newElement_0_e;
        chip::JniReferences::GetInstance().CreateArrayList(newElement_0_e);

        auto iter_newElement_0_e_2 = entry_0.e.begin();
        while (iter_newElement_0_e_2.Next())
        {
            auto & entry_2 = iter_newElement_0_e_2.GetValue();
            jobject newElement_2;
            std::string newElement_2ClassName     = "java/lang/Long";
            std::string newElement_2CtorSignature = "(J)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint32_t>(
                newElement_2ClassName.c_str(), newElement_2CtorSignature.c_str(), entry_2, newElement_2);
            chip::JniReferences::GetInstance().AddToList(newElement_0_e, newElement_2);
        }
        jobject newElement_0_f;
        chip::JniReferences::GetInstance().CreateArrayList(newElement_0_f);

        auto iter_newElement_0_f_2 = entry_0.f.begin();
        while (iter_newElement_0_f_2.Next())
        {
            auto & entry_2 = iter_newElement_0_f_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_f, newElement_2);
        }
        jobject newElement_0_g;
        chip::JniReferences::GetInstance().CreateArrayList(newElement_0_g);

        auto iter_newElement_0_g_2 = entry_0.g.begin();
        while (iter_newElement_0_g_2.Next())
        {
            auto & entry_2 = iter_newElement_0_g_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_g, newElement_2);
        }

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

        newElement_0 = env->NewObject(nestedStructListStructClass_1, nestedStructListStructCtor_1, newElement_0_a, newElement_0_b,
                                      newElement_0_c, newElement_0_d, newElement_0_e, newElement_0_f, newElement_0_g);
        chip::JniReferences::GetInstance().AddToList(arg1, newElement_0);
    }
    jobject arg2;
    chip::JniReferences::GetInstance().CreateArrayList(arg2);

    auto iter_arg2_0 = dataResponse.arg2.begin();
    while (iter_arg2_0.Next())
    {
        auto & entry_0 = iter_arg2_0.GetValue();
        jobject newElement_0;
        jobject newElement_0_a;
        std::string newElement_0_aClassName     = "java/lang/Integer";
        std::string newElement_0_aCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_aClassName.c_str(), newElement_0_aCtorSignature.c_str(), entry_0.a, newElement_0_a);
        jobject newElement_0_b;
        std::string newElement_0_bClassName     = "java/lang/Boolean";
        std::string newElement_0_bCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(newElement_0_bClassName.c_str(),
                                                                   newElement_0_bCtorSignature.c_str(), entry_0.b, newElement_0_b);
        jobject newElement_0_c;
        std::string newElement_0_cClassName     = "java/lang/Integer";
        std::string newElement_0_cCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_cClassName.c_str(), newElement_0_cCtorSignature.c_str(), static_cast<uint8_t>(entry_0.c), newElement_0_c);
        jobject newElement_0_d;
        jbyteArray newElement_0_dByteArray = env->NewByteArray(static_cast<jsize>(entry_0.d.size()));
        env->SetByteArrayRegion(newElement_0_dByteArray, 0, static_cast<jsize>(entry_0.d.size()),
                                reinterpret_cast<const jbyte *>(entry_0.d.data()));
        newElement_0_d = newElement_0_dByteArray;
        jobject newElement_0_e;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.e, newElement_0_e));
        jobject newElement_0_f;
        std::string newElement_0_fClassName     = "java/lang/Integer";
        std::string newElement_0_fCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            newElement_0_fClassName.c_str(), newElement_0_fCtorSignature.c_str(), entry_0.f.Raw(), newElement_0_f);
        jobject newElement_0_g;
        std::string newElement_0_gClassName     = "java/lang/Float";
        std::string newElement_0_gCtorSignature = "(F)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<float>(newElement_0_gClassName.c_str(),
                                                                    newElement_0_gCtorSignature.c_str(), entry_0.g, newElement_0_g);
        jobject newElement_0_h;
        std::string newElement_0_hClassName     = "java/lang/Double";
        std::string newElement_0_hCtorSignature = "(D)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<double>(
            newElement_0_hClassName.c_str(), newElement_0_hCtorSignature.c_str(), entry_0.h, newElement_0_h);

        jclass simpleStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$UnitTestingClusterSimpleStruct", simpleStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterSimpleStruct");
            return;
        }
        jmethodID simpleStructStructCtor_1 =
            env->GetMethodID(simpleStructStructClass_1, "<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_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$UnitTestingClusterSimpleStruct constructor");
            return;
        }

        newElement_0 =
            env->NewObject(simpleStructStructClass_1, simpleStructStructCtor_1, newElement_0_a, newElement_0_b, newElement_0_c,
                           newElement_0_d, newElement_0_e, newElement_0_f, newElement_0_g, newElement_0_h);
        chip::JniReferences::GetInstance().AddToList(arg2, newElement_0);
    }
    jobject arg3;
    chip::JniReferences::GetInstance().CreateArrayList(arg3);

    auto iter_arg3_0 = dataResponse.arg3.begin();
    while (iter_arg3_0.Next())
    {
        auto & entry_0 = iter_arg3_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(arg3, newElement_0);
    }
    jobject arg4;
    chip::JniReferences::GetInstance().CreateArrayList(arg4);

    auto iter_arg4_0 = dataResponse.arg4.begin();
    while (iter_arg4_0.Next())
    {
        auto & entry_0 = iter_arg4_0.GetValue();
        jobject newElement_0;
        std::string newElement_0ClassName     = "java/lang/Boolean";
        std::string newElement_0CtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(),
                                                                   entry_0, newElement_0);
        chip::JniReferences::GetInstance().AddToList(arg4, newElement_0);
    }
    jobject arg5;
    std::string arg5ClassName     = "java/lang/Integer";
    std::string arg5CtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(arg5ClassName.c_str(), arg5CtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.arg5), arg5);
    jobject arg6;
    std::string arg6ClassName     = "java/lang/Boolean";
    std::string arg6CtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(arg6ClassName.c_str(), arg6CtorSignature.c_str(), dataResponse.arg6,
                                                               arg6);

    env->CallVoidMethod(javaCallbackRef, javaMethod, arg1, arg2, arg3, arg4, arg5, arg6);
}
CHIPUnitTestingClusterTestListInt8UReverseResponseCallback::CHIPUnitTestingClusterTestListInt8UReverseResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterTestListInt8UReverseResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterTestListInt8UReverseResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::UnitTesting::Commands::TestListInt8UReverseResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterTestListInt8UReverseResponseCallback,
                    void (*)(CHIPUnitTestingClusterTestListInt8UReverseResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterTestListInt8UReverseResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterTestListInt8UReverseResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/ArrayList;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

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

    auto iter_arg1_0 = dataResponse.arg1.begin();
    while (iter_arg1_0.Next())
    {
        auto & entry_0 = iter_arg1_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(arg1, newElement_0);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, arg1);
}
CHIPUnitTestingClusterTestEnumsResponseCallback::CHIPUnitTestingClusterTestEnumsResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterTestEnumsResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterTestEnumsResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::UnitTesting::Commands::TestEnumsResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterTestEnumsResponseCallback, void (*)(CHIPUnitTestingClusterTestEnumsResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterTestEnumsResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterTestEnumsResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/lang/Integer;)V",
                                                  &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject arg1;
    std::string arg1ClassName     = "java/lang/Integer";
    std::string arg1CtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(arg1ClassName.c_str(), arg1CtorSignature.c_str(),
                                                                   static_cast<uint16_t>(dataResponse.arg1), arg1);
    jobject arg2;
    std::string arg2ClassName     = "java/lang/Integer";
    std::string arg2CtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(arg2ClassName.c_str(), arg2CtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.arg2), arg2);

    env->CallVoidMethod(javaCallbackRef, javaMethod, arg1, arg2);
}
CHIPUnitTestingClusterTestNullableOptionalResponseCallback::CHIPUnitTestingClusterTestNullableOptionalResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterTestNullableOptionalResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterTestNullableOptionalResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::UnitTesting::Commands::TestNullableOptionalResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterTestNullableOptionalResponseCallback,
                    void (*)(CHIPUnitTestingClusterTestNullableOptionalResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterTestNullableOptionalResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterTestNullableOptionalResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess", "(Ljava/lang/Boolean;Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject wasPresent;
    std::string wasPresentClassName     = "java/lang/Boolean";
    std::string wasPresentCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(wasPresentClassName.c_str(), wasPresentCtorSignature.c_str(),
                                                               dataResponse.wasPresent, wasPresent);
    jobject wasNull;
    if (!dataResponse.wasNull.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, wasNull);
    }
    else
    {
        jobject wasNullInsideOptional;
        std::string wasNullInsideOptionalClassName     = "java/lang/Boolean";
        std::string wasNullInsideOptionalCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(wasNullInsideOptionalClassName.c_str(),
                                                                   wasNullInsideOptionalCtorSignature.c_str(),
                                                                   dataResponse.wasNull.Value(), wasNullInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(wasNullInsideOptional, wasNull);
    }
    jobject value;
    if (!dataResponse.value.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, value);
    }
    else
    {
        jobject valueInsideOptional;
        std::string valueInsideOptionalClassName     = "java/lang/Integer";
        std::string valueInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(valueInsideOptionalClassName.c_str(),
                                                                      valueInsideOptionalCtorSignature.c_str(),
                                                                      dataResponse.value.Value(), valueInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(valueInsideOptional, value);
    }
    jobject originalValue;
    if (!dataResponse.originalValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, originalValue);
    }
    else
    {
        jobject originalValueInsideOptional;
        if (dataResponse.originalValue.Value().IsNull())
        {
            originalValueInsideOptional = nullptr;
        }
        else
        {
            std::string originalValueInsideOptionalClassName     = "java/lang/Integer";
            std::string originalValueInsideOptionalCtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                originalValueInsideOptionalClassName.c_str(), originalValueInsideOptionalCtorSignature.c_str(),
                dataResponse.originalValue.Value().Value(), originalValueInsideOptional);
        }
        chip::JniReferences::GetInstance().CreateOptional(originalValueInsideOptional, originalValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, wasPresent, wasNull, value, originalValue);
}
CHIPUnitTestingClusterTestComplexNullableOptionalResponseCallback::
    CHIPUnitTestingClusterTestComplexNullableOptionalResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterTestComplexNullableOptionalResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterTestComplexNullableOptionalResponseCallback::CallbackFn(
    void * context,
    const chip::app::Clusters::UnitTesting::Commands::TestComplexNullableOptionalResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterTestComplexNullableOptionalResponseCallback,
                    void (*)(CHIPUnitTestingClusterTestComplexNullableOptionalResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterTestComplexNullableOptionalResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterTestComplexNullableOptionalResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess",
        "(Ljava/lang/Boolean;Ljava/util/Optional;Ljava/lang/Boolean;Ljava/util/Optional;Ljava/lang/Boolean;Ljava/util/"
        "Optional;Ljava/util/Optional;Ljava/lang/Boolean;Ljava/util/Optional;Ljava/lang/Boolean;Ljava/util/Optional;Ljava/lang/"
        "Boolean;Ljava/util/Optional;Ljava/util/Optional;Ljava/lang/Boolean;Ljava/util/Optional;Ljava/lang/Boolean;Ljava/util/"
        "Optional;Ljava/lang/Boolean;Ljava/util/Optional;Ljava/util/Optional;Ljava/lang/Boolean;Ljava/util/Optional;Ljava/lang/"
        "Boolean;Ljava/util/Optional;Ljava/lang/Boolean;Ljava/util/Optional;Ljava/util/Optional;)V",
        &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject NullableIntWasNull;
    std::string NullableIntWasNullClassName     = "java/lang/Boolean";
    std::string NullableIntWasNullCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(NullableIntWasNullClassName.c_str(),
                                                               NullableIntWasNullCtorSignature.c_str(),
                                                               dataResponse.nullableIntWasNull, NullableIntWasNull);
    jobject NullableIntValue;
    if (!dataResponse.nullableIntValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableIntValue);
    }
    else
    {
        jobject NullableIntValueInsideOptional;
        std::string NullableIntValueInsideOptionalClassName     = "java/lang/Integer";
        std::string NullableIntValueInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            NullableIntValueInsideOptionalClassName.c_str(), NullableIntValueInsideOptionalCtorSignature.c_str(),
            dataResponse.nullableIntValue.Value(), NullableIntValueInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(NullableIntValueInsideOptional, NullableIntValue);
    }
    jobject OptionalIntWasPresent;
    std::string OptionalIntWasPresentClassName     = "java/lang/Boolean";
    std::string OptionalIntWasPresentCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(OptionalIntWasPresentClassName.c_str(),
                                                               OptionalIntWasPresentCtorSignature.c_str(),
                                                               dataResponse.optionalIntWasPresent, OptionalIntWasPresent);
    jobject OptionalIntValue;
    if (!dataResponse.optionalIntValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, OptionalIntValue);
    }
    else
    {
        jobject OptionalIntValueInsideOptional;
        std::string OptionalIntValueInsideOptionalClassName     = "java/lang/Integer";
        std::string OptionalIntValueInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            OptionalIntValueInsideOptionalClassName.c_str(), OptionalIntValueInsideOptionalCtorSignature.c_str(),
            dataResponse.optionalIntValue.Value(), OptionalIntValueInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(OptionalIntValueInsideOptional, OptionalIntValue);
    }
    jobject NullableOptionalIntWasPresent;
    std::string NullableOptionalIntWasPresentClassName     = "java/lang/Boolean";
    std::string NullableOptionalIntWasPresentCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
        NullableOptionalIntWasPresentClassName.c_str(), NullableOptionalIntWasPresentCtorSignature.c_str(),
        dataResponse.nullableOptionalIntWasPresent, NullableOptionalIntWasPresent);
    jobject NullableOptionalIntWasNull;
    if (!dataResponse.nullableOptionalIntWasNull.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableOptionalIntWasNull);
    }
    else
    {
        jobject NullableOptionalIntWasNullInsideOptional;
        std::string NullableOptionalIntWasNullInsideOptionalClassName     = "java/lang/Boolean";
        std::string NullableOptionalIntWasNullInsideOptionalCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(NullableOptionalIntWasNullInsideOptionalClassName.c_str(),
                                                                   NullableOptionalIntWasNullInsideOptionalCtorSignature.c_str(),
                                                                   dataResponse.nullableOptionalIntWasNull.Value(),
                                                                   NullableOptionalIntWasNullInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(NullableOptionalIntWasNullInsideOptional, NullableOptionalIntWasNull);
    }
    jobject NullableOptionalIntValue;
    if (!dataResponse.nullableOptionalIntValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableOptionalIntValue);
    }
    else
    {
        jobject NullableOptionalIntValueInsideOptional;
        std::string NullableOptionalIntValueInsideOptionalClassName     = "java/lang/Integer";
        std::string NullableOptionalIntValueInsideOptionalCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint16_t>(
            NullableOptionalIntValueInsideOptionalClassName.c_str(), NullableOptionalIntValueInsideOptionalCtorSignature.c_str(),
            dataResponse.nullableOptionalIntValue.Value(), NullableOptionalIntValueInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(NullableOptionalIntValueInsideOptional, NullableOptionalIntValue);
    }
    jobject NullableStringWasNull;
    std::string NullableStringWasNullClassName     = "java/lang/Boolean";
    std::string NullableStringWasNullCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(NullableStringWasNullClassName.c_str(),
                                                               NullableStringWasNullCtorSignature.c_str(),
                                                               dataResponse.nullableStringWasNull, NullableStringWasNull);
    jobject NullableStringValue;
    if (!dataResponse.nullableStringValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableStringValue);
    }
    else
    {
        jobject NullableStringValueInsideOptional;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.nullableStringValue.Value(),
                                                                             NullableStringValueInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(NullableStringValueInsideOptional, NullableStringValue);
    }
    jobject OptionalStringWasPresent;
    std::string OptionalStringWasPresentClassName     = "java/lang/Boolean";
    std::string OptionalStringWasPresentCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(OptionalStringWasPresentClassName.c_str(),
                                                               OptionalStringWasPresentCtorSignature.c_str(),
                                                               dataResponse.optionalStringWasPresent, OptionalStringWasPresent);
    jobject OptionalStringValue;
    if (!dataResponse.optionalStringValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, OptionalStringValue);
    }
    else
    {
        jobject OptionalStringValueInsideOptional;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.optionalStringValue.Value(),
                                                                             OptionalStringValueInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(OptionalStringValueInsideOptional, OptionalStringValue);
    }
    jobject NullableOptionalStringWasPresent;
    std::string NullableOptionalStringWasPresentClassName     = "java/lang/Boolean";
    std::string NullableOptionalStringWasPresentCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
        NullableOptionalStringWasPresentClassName.c_str(), NullableOptionalStringWasPresentCtorSignature.c_str(),
        dataResponse.nullableOptionalStringWasPresent, NullableOptionalStringWasPresent);
    jobject NullableOptionalStringWasNull;
    if (!dataResponse.nullableOptionalStringWasNull.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableOptionalStringWasNull);
    }
    else
    {
        jobject NullableOptionalStringWasNullInsideOptional;
        std::string NullableOptionalStringWasNullInsideOptionalClassName     = "java/lang/Boolean";
        std::string NullableOptionalStringWasNullInsideOptionalCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(NullableOptionalStringWasNullInsideOptionalClassName.c_str(),
                                                                   NullableOptionalStringWasNullInsideOptionalCtorSignature.c_str(),
                                                                   dataResponse.nullableOptionalStringWasNull.Value(),
                                                                   NullableOptionalStringWasNullInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(NullableOptionalStringWasNullInsideOptional,
                                                          NullableOptionalStringWasNull);
    }
    jobject NullableOptionalStringValue;
    if (!dataResponse.nullableOptionalStringValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableOptionalStringValue);
    }
    else
    {
        jobject NullableOptionalStringValueInsideOptional;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.nullableOptionalStringValue.Value(),
                                                                             NullableOptionalStringValueInsideOptional));
        chip::JniReferences::GetInstance().CreateOptional(NullableOptionalStringValueInsideOptional, NullableOptionalStringValue);
    }
    jobject NullableStructWasNull;
    std::string NullableStructWasNullClassName     = "java/lang/Boolean";
    std::string NullableStructWasNullCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(NullableStructWasNullClassName.c_str(),
                                                               NullableStructWasNullCtorSignature.c_str(),
                                                               dataResponse.nullableStructWasNull, NullableStructWasNull);
    jobject NullableStructValue;
    if (!dataResponse.nullableStructValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableStructValue);
    }
    else
    {
        jobject NullableStructValueInsideOptional;
        jobject NullableStructValueInsideOptional_a;
        std::string NullableStructValueInsideOptional_aClassName     = "java/lang/Integer";
        std::string NullableStructValueInsideOptional_aCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            NullableStructValueInsideOptional_aClassName.c_str(), NullableStructValueInsideOptional_aCtorSignature.c_str(),
            dataResponse.nullableStructValue.Value().a, NullableStructValueInsideOptional_a);
        jobject NullableStructValueInsideOptional_b;
        std::string NullableStructValueInsideOptional_bClassName     = "java/lang/Boolean";
        std::string NullableStructValueInsideOptional_bCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
            NullableStructValueInsideOptional_bClassName.c_str(), NullableStructValueInsideOptional_bCtorSignature.c_str(),
            dataResponse.nullableStructValue.Value().b, NullableStructValueInsideOptional_b);
        jobject NullableStructValueInsideOptional_c;
        std::string NullableStructValueInsideOptional_cClassName     = "java/lang/Integer";
        std::string NullableStructValueInsideOptional_cCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            NullableStructValueInsideOptional_cClassName.c_str(), NullableStructValueInsideOptional_cCtorSignature.c_str(),
            static_cast<uint8_t>(dataResponse.nullableStructValue.Value().c), NullableStructValueInsideOptional_c);
        jobject NullableStructValueInsideOptional_d;
        jbyteArray NullableStructValueInsideOptional_dByteArray =
            env->NewByteArray(static_cast<jsize>(dataResponse.nullableStructValue.Value().d.size()));
        env->SetByteArrayRegion(NullableStructValueInsideOptional_dByteArray, 0,
                                static_cast<jsize>(dataResponse.nullableStructValue.Value().d.size()),
                                reinterpret_cast<const jbyte *>(dataResponse.nullableStructValue.Value().d.data()));
        NullableStructValueInsideOptional_d = NullableStructValueInsideOptional_dByteArray;
        jobject NullableStructValueInsideOptional_e;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.nullableStructValue.Value().e,
                                                                             NullableStructValueInsideOptional_e));
        jobject NullableStructValueInsideOptional_f;
        std::string NullableStructValueInsideOptional_fClassName     = "java/lang/Integer";
        std::string NullableStructValueInsideOptional_fCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            NullableStructValueInsideOptional_fClassName.c_str(), NullableStructValueInsideOptional_fCtorSignature.c_str(),
            dataResponse.nullableStructValue.Value().f.Raw(), NullableStructValueInsideOptional_f);
        jobject NullableStructValueInsideOptional_g;
        std::string NullableStructValueInsideOptional_gClassName     = "java/lang/Float";
        std::string NullableStructValueInsideOptional_gCtorSignature = "(F)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<float>(
            NullableStructValueInsideOptional_gClassName.c_str(), NullableStructValueInsideOptional_gCtorSignature.c_str(),
            dataResponse.nullableStructValue.Value().g, NullableStructValueInsideOptional_g);
        jobject NullableStructValueInsideOptional_h;
        std::string NullableStructValueInsideOptional_hClassName     = "java/lang/Double";
        std::string NullableStructValueInsideOptional_hCtorSignature = "(D)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<double>(
            NullableStructValueInsideOptional_hClassName.c_str(), NullableStructValueInsideOptional_hCtorSignature.c_str(),
            dataResponse.nullableStructValue.Value().h, NullableStructValueInsideOptional_h);

        jclass simpleStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$UnitTestingClusterSimpleStruct", simpleStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterSimpleStruct");
            return;
        }
        jmethodID simpleStructStructCtor_1 =
            env->GetMethodID(simpleStructStructClass_1, "<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_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$UnitTestingClusterSimpleStruct constructor");
            return;
        }

        NullableStructValueInsideOptional = env->NewObject(
            simpleStructStructClass_1, simpleStructStructCtor_1, NullableStructValueInsideOptional_a,
            NullableStructValueInsideOptional_b, NullableStructValueInsideOptional_c, NullableStructValueInsideOptional_d,
            NullableStructValueInsideOptional_e, NullableStructValueInsideOptional_f, NullableStructValueInsideOptional_g,
            NullableStructValueInsideOptional_h);
        chip::JniReferences::GetInstance().CreateOptional(NullableStructValueInsideOptional, NullableStructValue);
    }
    jobject OptionalStructWasPresent;
    std::string OptionalStructWasPresentClassName     = "java/lang/Boolean";
    std::string OptionalStructWasPresentCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(OptionalStructWasPresentClassName.c_str(),
                                                               OptionalStructWasPresentCtorSignature.c_str(),
                                                               dataResponse.optionalStructWasPresent, OptionalStructWasPresent);
    jobject OptionalStructValue;
    if (!dataResponse.optionalStructValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, OptionalStructValue);
    }
    else
    {
        jobject OptionalStructValueInsideOptional;
        jobject OptionalStructValueInsideOptional_a;
        std::string OptionalStructValueInsideOptional_aClassName     = "java/lang/Integer";
        std::string OptionalStructValueInsideOptional_aCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            OptionalStructValueInsideOptional_aClassName.c_str(), OptionalStructValueInsideOptional_aCtorSignature.c_str(),
            dataResponse.optionalStructValue.Value().a, OptionalStructValueInsideOptional_a);
        jobject OptionalStructValueInsideOptional_b;
        std::string OptionalStructValueInsideOptional_bClassName     = "java/lang/Boolean";
        std::string OptionalStructValueInsideOptional_bCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
            OptionalStructValueInsideOptional_bClassName.c_str(), OptionalStructValueInsideOptional_bCtorSignature.c_str(),
            dataResponse.optionalStructValue.Value().b, OptionalStructValueInsideOptional_b);
        jobject OptionalStructValueInsideOptional_c;
        std::string OptionalStructValueInsideOptional_cClassName     = "java/lang/Integer";
        std::string OptionalStructValueInsideOptional_cCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            OptionalStructValueInsideOptional_cClassName.c_str(), OptionalStructValueInsideOptional_cCtorSignature.c_str(),
            static_cast<uint8_t>(dataResponse.optionalStructValue.Value().c), OptionalStructValueInsideOptional_c);
        jobject OptionalStructValueInsideOptional_d;
        jbyteArray OptionalStructValueInsideOptional_dByteArray =
            env->NewByteArray(static_cast<jsize>(dataResponse.optionalStructValue.Value().d.size()));
        env->SetByteArrayRegion(OptionalStructValueInsideOptional_dByteArray, 0,
                                static_cast<jsize>(dataResponse.optionalStructValue.Value().d.size()),
                                reinterpret_cast<const jbyte *>(dataResponse.optionalStructValue.Value().d.data()));
        OptionalStructValueInsideOptional_d = OptionalStructValueInsideOptional_dByteArray;
        jobject OptionalStructValueInsideOptional_e;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.optionalStructValue.Value().e,
                                                                             OptionalStructValueInsideOptional_e));
        jobject OptionalStructValueInsideOptional_f;
        std::string OptionalStructValueInsideOptional_fClassName     = "java/lang/Integer";
        std::string OptionalStructValueInsideOptional_fCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            OptionalStructValueInsideOptional_fClassName.c_str(), OptionalStructValueInsideOptional_fCtorSignature.c_str(),
            dataResponse.optionalStructValue.Value().f.Raw(), OptionalStructValueInsideOptional_f);
        jobject OptionalStructValueInsideOptional_g;
        std::string OptionalStructValueInsideOptional_gClassName     = "java/lang/Float";
        std::string OptionalStructValueInsideOptional_gCtorSignature = "(F)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<float>(
            OptionalStructValueInsideOptional_gClassName.c_str(), OptionalStructValueInsideOptional_gCtorSignature.c_str(),
            dataResponse.optionalStructValue.Value().g, OptionalStructValueInsideOptional_g);
        jobject OptionalStructValueInsideOptional_h;
        std::string OptionalStructValueInsideOptional_hClassName     = "java/lang/Double";
        std::string OptionalStructValueInsideOptional_hCtorSignature = "(D)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<double>(
            OptionalStructValueInsideOptional_hClassName.c_str(), OptionalStructValueInsideOptional_hCtorSignature.c_str(),
            dataResponse.optionalStructValue.Value().h, OptionalStructValueInsideOptional_h);

        jclass simpleStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$UnitTestingClusterSimpleStruct", simpleStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterSimpleStruct");
            return;
        }
        jmethodID simpleStructStructCtor_1 =
            env->GetMethodID(simpleStructStructClass_1, "<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_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$UnitTestingClusterSimpleStruct constructor");
            return;
        }

        OptionalStructValueInsideOptional = env->NewObject(
            simpleStructStructClass_1, simpleStructStructCtor_1, OptionalStructValueInsideOptional_a,
            OptionalStructValueInsideOptional_b, OptionalStructValueInsideOptional_c, OptionalStructValueInsideOptional_d,
            OptionalStructValueInsideOptional_e, OptionalStructValueInsideOptional_f, OptionalStructValueInsideOptional_g,
            OptionalStructValueInsideOptional_h);
        chip::JniReferences::GetInstance().CreateOptional(OptionalStructValueInsideOptional, OptionalStructValue);
    }
    jobject NullableOptionalStructWasPresent;
    std::string NullableOptionalStructWasPresentClassName     = "java/lang/Boolean";
    std::string NullableOptionalStructWasPresentCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
        NullableOptionalStructWasPresentClassName.c_str(), NullableOptionalStructWasPresentCtorSignature.c_str(),
        dataResponse.nullableOptionalStructWasPresent, NullableOptionalStructWasPresent);
    jobject NullableOptionalStructWasNull;
    if (!dataResponse.nullableOptionalStructWasNull.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableOptionalStructWasNull);
    }
    else
    {
        jobject NullableOptionalStructWasNullInsideOptional;
        std::string NullableOptionalStructWasNullInsideOptionalClassName     = "java/lang/Boolean";
        std::string NullableOptionalStructWasNullInsideOptionalCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(NullableOptionalStructWasNullInsideOptionalClassName.c_str(),
                                                                   NullableOptionalStructWasNullInsideOptionalCtorSignature.c_str(),
                                                                   dataResponse.nullableOptionalStructWasNull.Value(),
                                                                   NullableOptionalStructWasNullInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(NullableOptionalStructWasNullInsideOptional,
                                                          NullableOptionalStructWasNull);
    }
    jobject NullableOptionalStructValue;
    if (!dataResponse.nullableOptionalStructValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableOptionalStructValue);
    }
    else
    {
        jobject NullableOptionalStructValueInsideOptional;
        jobject NullableOptionalStructValueInsideOptional_a;
        std::string NullableOptionalStructValueInsideOptional_aClassName     = "java/lang/Integer";
        std::string NullableOptionalStructValueInsideOptional_aCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            NullableOptionalStructValueInsideOptional_aClassName.c_str(),
            NullableOptionalStructValueInsideOptional_aCtorSignature.c_str(), dataResponse.nullableOptionalStructValue.Value().a,
            NullableOptionalStructValueInsideOptional_a);
        jobject NullableOptionalStructValueInsideOptional_b;
        std::string NullableOptionalStructValueInsideOptional_bClassName     = "java/lang/Boolean";
        std::string NullableOptionalStructValueInsideOptional_bCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(NullableOptionalStructValueInsideOptional_bClassName.c_str(),
                                                                   NullableOptionalStructValueInsideOptional_bCtorSignature.c_str(),
                                                                   dataResponse.nullableOptionalStructValue.Value().b,
                                                                   NullableOptionalStructValueInsideOptional_b);
        jobject NullableOptionalStructValueInsideOptional_c;
        std::string NullableOptionalStructValueInsideOptional_cClassName     = "java/lang/Integer";
        std::string NullableOptionalStructValueInsideOptional_cCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            NullableOptionalStructValueInsideOptional_cClassName.c_str(),
            NullableOptionalStructValueInsideOptional_cCtorSignature.c_str(),
            static_cast<uint8_t>(dataResponse.nullableOptionalStructValue.Value().c), NullableOptionalStructValueInsideOptional_c);
        jobject NullableOptionalStructValueInsideOptional_d;
        jbyteArray NullableOptionalStructValueInsideOptional_dByteArray =
            env->NewByteArray(static_cast<jsize>(dataResponse.nullableOptionalStructValue.Value().d.size()));
        env->SetByteArrayRegion(NullableOptionalStructValueInsideOptional_dByteArray, 0,
                                static_cast<jsize>(dataResponse.nullableOptionalStructValue.Value().d.size()),
                                reinterpret_cast<const jbyte *>(dataResponse.nullableOptionalStructValue.Value().d.data()));
        NullableOptionalStructValueInsideOptional_d = NullableOptionalStructValueInsideOptional_dByteArray;
        jobject NullableOptionalStructValueInsideOptional_e;
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.nullableOptionalStructValue.Value().e,
                                                                             NullableOptionalStructValueInsideOptional_e));
        jobject NullableOptionalStructValueInsideOptional_f;
        std::string NullableOptionalStructValueInsideOptional_fClassName     = "java/lang/Integer";
        std::string NullableOptionalStructValueInsideOptional_fCtorSignature = "(I)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
            NullableOptionalStructValueInsideOptional_fClassName.c_str(),
            NullableOptionalStructValueInsideOptional_fCtorSignature.c_str(),
            dataResponse.nullableOptionalStructValue.Value().f.Raw(), NullableOptionalStructValueInsideOptional_f);
        jobject NullableOptionalStructValueInsideOptional_g;
        std::string NullableOptionalStructValueInsideOptional_gClassName     = "java/lang/Float";
        std::string NullableOptionalStructValueInsideOptional_gCtorSignature = "(F)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<float>(
            NullableOptionalStructValueInsideOptional_gClassName.c_str(),
            NullableOptionalStructValueInsideOptional_gCtorSignature.c_str(), dataResponse.nullableOptionalStructValue.Value().g,
            NullableOptionalStructValueInsideOptional_g);
        jobject NullableOptionalStructValueInsideOptional_h;
        std::string NullableOptionalStructValueInsideOptional_hClassName     = "java/lang/Double";
        std::string NullableOptionalStructValueInsideOptional_hCtorSignature = "(D)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<double>(
            NullableOptionalStructValueInsideOptional_hClassName.c_str(),
            NullableOptionalStructValueInsideOptional_hCtorSignature.c_str(), dataResponse.nullableOptionalStructValue.Value().h,
            NullableOptionalStructValueInsideOptional_h);

        jclass simpleStructStructClass_1;
        err = chip::JniReferences::GetInstance().GetClassRef(
            env, "chip/devicecontroller/ChipStructs$UnitTestingClusterSimpleStruct", simpleStructStructClass_1);
        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterSimpleStruct");
            return;
        }
        jmethodID simpleStructStructCtor_1 =
            env->GetMethodID(simpleStructStructClass_1, "<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_1 == nullptr)
        {
            ChipLogError(Zcl, "Could not find ChipStructs$UnitTestingClusterSimpleStruct constructor");
            return;
        }

        NullableOptionalStructValueInsideOptional =
            env->NewObject(simpleStructStructClass_1, simpleStructStructCtor_1, NullableOptionalStructValueInsideOptional_a,
                           NullableOptionalStructValueInsideOptional_b, NullableOptionalStructValueInsideOptional_c,
                           NullableOptionalStructValueInsideOptional_d, NullableOptionalStructValueInsideOptional_e,
                           NullableOptionalStructValueInsideOptional_f, NullableOptionalStructValueInsideOptional_g,
                           NullableOptionalStructValueInsideOptional_h);
        chip::JniReferences::GetInstance().CreateOptional(NullableOptionalStructValueInsideOptional, NullableOptionalStructValue);
    }
    jobject NullableListWasNull;
    std::string NullableListWasNullClassName     = "java/lang/Boolean";
    std::string NullableListWasNullCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(NullableListWasNullClassName.c_str(),
                                                               NullableListWasNullCtorSignature.c_str(),
                                                               dataResponse.nullableListWasNull, NullableListWasNull);
    jobject NullableListValue;
    if (!dataResponse.nullableListValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableListValue);
    }
    else
    {
        jobject NullableListValueInsideOptional;
        chip::JniReferences::GetInstance().CreateArrayList(NullableListValueInsideOptional);

        auto iter_NullableListValueInsideOptional_1 = dataResponse.nullableListValue.Value().begin();
        while (iter_NullableListValueInsideOptional_1.Next())
        {
            auto & entry_1 = iter_NullableListValueInsideOptional_1.GetValue();
            jobject newElement_1;
            std::string newElement_1ClassName     = "java/lang/Integer";
            std::string newElement_1CtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_1ClassName.c_str(), newElement_1CtorSignature.c_str(), static_cast<uint8_t>(entry_1), newElement_1);
            chip::JniReferences::GetInstance().AddToList(NullableListValueInsideOptional, newElement_1);
        }
        chip::JniReferences::GetInstance().CreateOptional(NullableListValueInsideOptional, NullableListValue);
    }
    jobject OptionalListWasPresent;
    std::string OptionalListWasPresentClassName     = "java/lang/Boolean";
    std::string OptionalListWasPresentCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(OptionalListWasPresentClassName.c_str(),
                                                               OptionalListWasPresentCtorSignature.c_str(),
                                                               dataResponse.optionalListWasPresent, OptionalListWasPresent);
    jobject OptionalListValue;
    if (!dataResponse.optionalListValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, OptionalListValue);
    }
    else
    {
        jobject OptionalListValueInsideOptional;
        chip::JniReferences::GetInstance().CreateArrayList(OptionalListValueInsideOptional);

        auto iter_OptionalListValueInsideOptional_1 = dataResponse.optionalListValue.Value().begin();
        while (iter_OptionalListValueInsideOptional_1.Next())
        {
            auto & entry_1 = iter_OptionalListValueInsideOptional_1.GetValue();
            jobject newElement_1;
            std::string newElement_1ClassName     = "java/lang/Integer";
            std::string newElement_1CtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_1ClassName.c_str(), newElement_1CtorSignature.c_str(), static_cast<uint8_t>(entry_1), newElement_1);
            chip::JniReferences::GetInstance().AddToList(OptionalListValueInsideOptional, newElement_1);
        }
        chip::JniReferences::GetInstance().CreateOptional(OptionalListValueInsideOptional, OptionalListValue);
    }
    jobject NullableOptionalListWasPresent;
    std::string NullableOptionalListWasPresentClassName     = "java/lang/Boolean";
    std::string NullableOptionalListWasPresentCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(
        NullableOptionalListWasPresentClassName.c_str(), NullableOptionalListWasPresentCtorSignature.c_str(),
        dataResponse.nullableOptionalListWasPresent, NullableOptionalListWasPresent);
    jobject NullableOptionalListWasNull;
    if (!dataResponse.nullableOptionalListWasNull.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableOptionalListWasNull);
    }
    else
    {
        jobject NullableOptionalListWasNullInsideOptional;
        std::string NullableOptionalListWasNullInsideOptionalClassName     = "java/lang/Boolean";
        std::string NullableOptionalListWasNullInsideOptionalCtorSignature = "(Z)V";
        chip::JniReferences::GetInstance().CreateBoxedObject<bool>(NullableOptionalListWasNullInsideOptionalClassName.c_str(),
                                                                   NullableOptionalListWasNullInsideOptionalCtorSignature.c_str(),
                                                                   dataResponse.nullableOptionalListWasNull.Value(),
                                                                   NullableOptionalListWasNullInsideOptional);
        chip::JniReferences::GetInstance().CreateOptional(NullableOptionalListWasNullInsideOptional, NullableOptionalListWasNull);
    }
    jobject NullableOptionalListValue;
    if (!dataResponse.nullableOptionalListValue.HasValue())
    {
        chip::JniReferences::GetInstance().CreateOptional(nullptr, NullableOptionalListValue);
    }
    else
    {
        jobject NullableOptionalListValueInsideOptional;
        chip::JniReferences::GetInstance().CreateArrayList(NullableOptionalListValueInsideOptional);

        auto iter_NullableOptionalListValueInsideOptional_1 = dataResponse.nullableOptionalListValue.Value().begin();
        while (iter_NullableOptionalListValueInsideOptional_1.Next())
        {
            auto & entry_1 = iter_NullableOptionalListValueInsideOptional_1.GetValue();
            jobject newElement_1;
            std::string newElement_1ClassName     = "java/lang/Integer";
            std::string newElement_1CtorSignature = "(I)V";
            chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                newElement_1ClassName.c_str(), newElement_1CtorSignature.c_str(), static_cast<uint8_t>(entry_1), newElement_1);
            chip::JniReferences::GetInstance().AddToList(NullableOptionalListValueInsideOptional, newElement_1);
        }
        chip::JniReferences::GetInstance().CreateOptional(NullableOptionalListValueInsideOptional, NullableOptionalListValue);
    }

    env->CallVoidMethod(javaCallbackRef, javaMethod, NullableIntWasNull, NullableIntValue, OptionalIntWasPresent, OptionalIntValue,
                        NullableOptionalIntWasPresent, NullableOptionalIntWasNull, NullableOptionalIntValue, NullableStringWasNull,
                        NullableStringValue, OptionalStringWasPresent, OptionalStringValue, NullableOptionalStringWasPresent,
                        NullableOptionalStringWasNull, NullableOptionalStringValue, NullableStructWasNull, NullableStructValue,
                        OptionalStructWasPresent, OptionalStructValue, NullableOptionalStructWasPresent,
                        NullableOptionalStructWasNull, NullableOptionalStructValue, NullableListWasNull, NullableListValue,
                        OptionalListWasPresent, OptionalListValue, NullableOptionalListWasPresent, NullableOptionalListWasNull,
                        NullableOptionalListValue);
}
CHIPUnitTestingClusterBooleanResponseCallback::CHIPUnitTestingClusterBooleanResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterBooleanResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterBooleanResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::UnitTesting::Commands::BooleanResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterBooleanResponseCallback, void (*)(CHIPUnitTestingClusterBooleanResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterBooleanResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterBooleanResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Boolean;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject value;
    std::string valueClassName     = "java/lang/Boolean";
    std::string valueCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(valueClassName.c_str(), valueCtorSignature.c_str(),
                                                               dataResponse.value, value);

    env->CallVoidMethod(javaCallbackRef, javaMethod, value);
}
CHIPUnitTestingClusterSimpleStructResponseCallback::CHIPUnitTestingClusterSimpleStructResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterSimpleStructResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterSimpleStructResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::UnitTesting::Commands::SimpleStructResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterSimpleStructResponseCallback,
                    void (*)(CHIPUnitTestingClusterSimpleStructResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterSimpleStructResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterSimpleStructResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(
        env, javaCallbackRef, "onSuccess", "(Lchip/devicecontroller/ChipStructs$UnitTestingClusterSimpleStruct;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject arg1;
    jobject arg1_a;
    std::string arg1_aClassName     = "java/lang/Integer";
    std::string arg1_aCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(arg1_aClassName.c_str(), arg1_aCtorSignature.c_str(),
                                                                  dataResponse.arg1.a, arg1_a);
    jobject arg1_b;
    std::string arg1_bClassName     = "java/lang/Boolean";
    std::string arg1_bCtorSignature = "(Z)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<bool>(arg1_bClassName.c_str(), arg1_bCtorSignature.c_str(),
                                                               dataResponse.arg1.b, arg1_b);
    jobject arg1_c;
    std::string arg1_cClassName     = "java/lang/Integer";
    std::string arg1_cCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(arg1_cClassName.c_str(), arg1_cCtorSignature.c_str(),
                                                                  static_cast<uint8_t>(dataResponse.arg1.c), arg1_c);
    jobject arg1_d;
    jbyteArray arg1_dByteArray = env->NewByteArray(static_cast<jsize>(dataResponse.arg1.d.size()));
    env->SetByteArrayRegion(arg1_dByteArray, 0, static_cast<jsize>(dataResponse.arg1.d.size()),
                            reinterpret_cast<const jbyte *>(dataResponse.arg1.d.data()));
    arg1_d = arg1_dByteArray;
    jobject arg1_e;
    LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.arg1.e, arg1_e));
    jobject arg1_f;
    std::string arg1_fClassName     = "java/lang/Integer";
    std::string arg1_fCtorSignature = "(I)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(arg1_fClassName.c_str(), arg1_fCtorSignature.c_str(),
                                                                  dataResponse.arg1.f.Raw(), arg1_f);
    jobject arg1_g;
    std::string arg1_gClassName     = "java/lang/Float";
    std::string arg1_gCtorSignature = "(F)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<float>(arg1_gClassName.c_str(), arg1_gCtorSignature.c_str(),
                                                                dataResponse.arg1.g, arg1_g);
    jobject arg1_h;
    std::string arg1_hClassName     = "java/lang/Double";
    std::string arg1_hCtorSignature = "(D)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<double>(arg1_hClassName.c_str(), arg1_hCtorSignature.c_str(),
                                                                 dataResponse.arg1.h, arg1_h);

    jclass simpleStructStructClass_0;
    err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs$UnitTestingClusterSimpleStruct",
                                                         simpleStructStructClass_0);
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterSimpleStruct");
        return;
    }
    jmethodID simpleStructStructCtor_0 = env->GetMethodID(simpleStructStructClass_0, "<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_0 == nullptr)
    {
        ChipLogError(Zcl, "Could not find ChipStructs$UnitTestingClusterSimpleStruct constructor");
        return;
    }

    arg1 = env->NewObject(simpleStructStructClass_0, simpleStructStructCtor_0, arg1_a, arg1_b, arg1_c, arg1_d, arg1_e, arg1_f,
                          arg1_g, arg1_h);

    env->CallVoidMethod(javaCallbackRef, javaMethod, arg1);
}
CHIPUnitTestingClusterTestEmitTestEventResponseCallback::CHIPUnitTestingClusterTestEmitTestEventResponseCallback(
    jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterTestEmitTestEventResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterTestEmitTestEventResponseCallback::CallbackFn(
    void * context, const chip::app::Clusters::UnitTesting::Commands::TestEmitTestEventResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterTestEmitTestEventResponseCallback,
                    void (*)(CHIPUnitTestingClusterTestEmitTestEventResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterTestEmitTestEventResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterTestEmitTestEventResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject value;
    std::string valueClassName     = "java/lang/Long";
    std::string valueCtorSignature = "(J)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(valueClassName.c_str(), valueCtorSignature.c_str(),
                                                                   dataResponse.value, value);

    env->CallVoidMethod(javaCallbackRef, javaMethod, value);
}
CHIPUnitTestingClusterTestEmitTestFabricScopedEventResponseCallback::
    CHIPUnitTestingClusterTestEmitTestFabricScopedEventResponseCallback(jobject javaCallback) :
    Callback::Callback<CHIPUnitTestingClusterTestEmitTestFabricScopedEventResponseCallbackType>(CallbackFn, this)
{
    JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
    if (env == nullptr)
    {
        ChipLogError(Zcl, "Could not create global reference for Java callback");
        return;
    }

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

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

void CHIPUnitTestingClusterTestEmitTestFabricScopedEventResponseCallback::CallbackFn(
    void * context,
    const chip::app::Clusters::UnitTesting::Commands::TestEmitTestFabricScopedEventResponse::DecodableType & dataResponse)
{
    chip::DeviceLayer::StackUnlock unlock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
    jobject javaCallbackRef;
    jmethodID javaMethod;

    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));

    std::unique_ptr<CHIPUnitTestingClusterTestEmitTestFabricScopedEventResponseCallback,
                    void (*)(CHIPUnitTestingClusterTestEmitTestFabricScopedEventResponseCallback *)>
        cppCallback(reinterpret_cast<CHIPUnitTestingClusterTestEmitTestFabricScopedEventResponseCallback *>(context),
                    chip::Platform::Delete<CHIPUnitTestingClusterTestEmitTestFabricScopedEventResponseCallback>);
    VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));

    javaCallbackRef = cppCallback->javaCallbackRef;
    // Java callback is allowed to be null, exit early if this is the case.
    VerifyOrReturn(javaCallbackRef != nullptr);

    err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod);
    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));

    jobject value;
    std::string valueClassName     = "java/lang/Long";
    std::string valueCtorSignature = "(J)V";
    chip::JniReferences::GetInstance().CreateBoxedObject<uint64_t>(valueClassName.c_str(), valueCtorSignature.c_str(),
                                                                   dataResponse.value, value);

    env->CallVoidMethod(javaCallbackRef, javaMethod, value);
}
} // namespace chip
