/*
 *
 *    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;
                chip::JniReferences::GetInstance().CreateArrayList(newElement_3_attributeValue);

                auto iter_newElement_3_attributeValue_5 = entry_3.attributeValue.begin();
                while (iter_newElement_3_attributeValue_5.Next())
                {
                    auto & entry_5 = iter_newElement_3_attributeValue_5.GetValue();
                    jobject newElement_5;
                    std::string newElement_5ClassName     = "java/lang/Integer";
                    std::string newElement_5CtorSignature = "(I)V";
                    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                        newElement_5ClassName.c_str(), newElement_5CtorSignature.c_str(), entry_5, newElement_5);
                    chip::JniReferences::GetInstance().AddToList(newElement_3_attributeValue, newElement_5);
                }

                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/util/ArrayList;)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;
                chip::JniReferences::GetInstance().CreateArrayList(newElement_3_attributeValue);

                auto iter_newElement_3_attributeValue_5 = entry_3.attributeValue.begin();
                while (iter_newElement_3_attributeValue_5.Next())
                {
                    auto & entry_5 = iter_newElement_3_attributeValue_5.GetValue();
                    jobject newElement_5;
                    std::string newElement_5ClassName     = "java/lang/Integer";
                    std::string newElement_5CtorSignature = "(I)V";
                    chip::JniReferences::GetInstance().CreateBoxedObject<uint8_t>(
                        newElement_5ClassName.c_str(), newElement_5CtorSignature.c_str(), entry_5, newElement_5);
                    chip::JniReferences::GetInstance().AddToList(newElement_3_attributeValue, newElement_5);
                }

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