{{#unless omitDeclaration}}
jobject {{target}};
{{/unless}}
{{#if isOptional}}
if (!{{source}}.HasValue()) {
  chip::JniReferences::GetInstance().CreateOptional(nullptr, {{target}});
} else {
  jobject {{target}}InsideOptional;
  {{>decode_value target=(concat target "InsideOptional") source=(concat source ".Value()") cluster=cluster depth=(incrementDepth depth) isOptional=false omitDeclaration=true earlyReturn=earlyReturn}}
  chip::JniReferences::GetInstance().CreateOptional({{target}}InsideOptional, {{target}});
}
{{else if isNullable}}
if ({{source}}.IsNull()) {
  {{target}} = nullptr;
} else {
  {{>decode_value target=target source=(concat source ".Value()") cluster=cluster depth=(incrementDepth depth) isNullable=false omitDeclaration=true earlyReturn=earlyReturn}}
}
{{else if isArray}}
  chip::JniReferences::GetInstance().CreateArrayList({{target}});

  auto iter_{{target}}_{{depth}} = {{source}}.begin();
  while (iter_{{target}}_{{depth}}.Next())
  {
    auto & entry_{{depth}} = iter_{{target}}_{{depth}}.GetValue();
    {{>decode_value target=(concat "newElement_" depth) source=(concat "entry_" depth) cluster=cluster depth=(incrementDepth depth) isArray=false forceNotList=true omitDeclaration=false earlyReturn=earlyReturn}}
    chip::JniReferences::GetInstance().AddToList({{target}}, newElement_{{depth}});
  }
{{else}}
  {{#if_is_struct type}}
    {{#zcl_struct_items_by_struct_and_cluster_name type cluster}}
      {{>decode_value target=(concat ../target "_" (asLowerCamelCase label)) source=(concat ../source "." (asLowerCamelCase label)) cluster=../cluster depth=(incrementDepth ../depth) omitDeclaration=false earlyReturn=../earlyReturn}}
    {{/zcl_struct_items_by_struct_and_cluster_name}}

    jclass {{asLowerCamelCase type}}StructClass_{{depth}};
    err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs${{asUpperCamelCase cluster}}Cluster{{asUpperCamelCase type}}", {{asLowerCamelCase type}}StructClass_{{depth}});
    if (err != CHIP_NO_ERROR) {
      ChipLogError(Zcl, "Could not find class ChipStructs${{asUpperCamelCase cluster}}Cluster{{asUpperCamelCase type}}");
      return {{earlyReturn}};
    }
    jmethodID {{asLowerCamelCase type}}StructCtor_{{depth}} = env->GetMethodID({{asLowerCamelCase type}}StructClass_{{depth}}, "<init>"
        , "({{#zcl_struct_items_by_struct_and_cluster_name type cluster}}{{asJniSignature type null (asUpperCamelCase ../cluster) true}}{{/zcl_struct_items_by_struct_and_cluster_name}})V");
    if ({{asLowerCamelCase type}}StructCtor_{{depth}} == nullptr) {
      ChipLogError(Zcl, "Could not find ChipStructs${{asUpperCamelCase cluster}}Cluster{{asUpperCamelCase type}} constructor");
      return {{earlyReturn}};
    }

    {{target}} = env->NewObject({{asLowerCamelCase type}}StructClass_{{depth}}, {{asLowerCamelCase type}}StructCtor_{{depth}}
      {{#zcl_struct_items_by_struct_and_cluster_name type cluster}}
      , {{../target}}_{{asLowerCamelCase label}}
      {{/zcl_struct_items_by_struct_and_cluster_name}}
    );
  {{else}}
    {{#if_is_strongly_typed_chip_enum type}}
      std::string {{target}}ClassName = "{{asJniClassName type null (asUpperCamelCase cluster)}}";
      std::string {{target}}CtorSignature = "({{asJniSignature type null (asUpperCamelCase cluster) false}})V";
      chip::JniReferences::GetInstance().CreateBoxedObject<{{asUnderlyingBasicType type}}>({{target}}ClassName.c_str(), {{target}}CtorSignature.c_str(), static_cast<{{asUnderlyingBasicType type}}>({{source}}), {{target}});
    {{else}}
      {{#if (isOctetString type)}}
        jbyteArray {{target}}ByteArray = env->NewByteArray(static_cast<jsize>({{source}}.size()));
        env->SetByteArrayRegion({{target}}ByteArray, 0, static_cast<jsize>({{source}}.size()), reinterpret_cast<const jbyte *>({{source}}.data()));
        {{target}} = {{target}}ByteArray;
      {{else if (isCharString type)}}
        LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF({{source}}, {{target}}));
      {{else}}
        std::string {{target}}ClassName = "{{asJniClassName type null (asUpperCamelCase cluster)}}";
        std::string {{target}}CtorSignature = "({{asJniSignature type null (asUpperCamelCase cluster) false}})V";
        {{#if_is_strongly_typed_bitmap type}}
          chip::JniReferences::GetInstance().CreateBoxedObject<{{asUnderlyingBasicType type}}>({{target}}ClassName.c_str(), {{target}}CtorSignature.c_str(), {{source}}.Raw(), {{target}});
        {{else}}
          chip::JniReferences::GetInstance().CreateBoxedObject<{{asUnderlyingBasicType type}}>({{target}}ClassName.c_str(), {{target}}CtorSignature.c_str(), {{source}}, {{target}});
        {{/if_is_strongly_typed_bitmap}}
      {{/if}}
    {{/if_is_strongly_typed_chip_enum}}
  {{/if_is_struct}}
{{/if}}