/*
 *
 *    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

package chip.devicecontroller;

import chip.clusterinfo.ClusterCommandCallback;
import chip.clusterinfo.ClusterInfo;
import chip.clusterinfo.CommandParameterInfo;
import chip.clusterinfo.CommandResponseInfo;
import chip.clusterinfo.DelegatedClusterCallback;
import chip.clusterinfo.InteractionInfo;
import chip.devicecontroller.ChipClusters.DefaultClusterCallback;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;

public class ClusterInfoMapping {

  public static class DelegatedCharStringAttributeCallback
      implements ChipClusters.CharStringAttributeCallback, DelegatedClusterCallback {
    /** Indicates a successful read for a CHAR_STRING attribute. */
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(String value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "String");
      responseValues.put(setupPINResponseValue, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedOctetStringAttributeCallback
      implements ChipClusters.OctetStringAttributeCallback, DelegatedClusterCallback {
    /** Indicates a successful read for an OCTET_STRING attribute. */
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(byte[] value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "byte[]");
      responseValues.put(setupPINResponseValue, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedIntegerAttributeCallback
      implements ChipClusters.IntegerAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(int value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "int");
      responseValues.put(setupPINResponseValue, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedLongAttributeCallback
      implements ChipClusters.LongAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "long");
      responseValues.put(setupPINResponseValue, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedBooleanAttributeCallback
      implements ChipClusters.BooleanAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(boolean value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "boolean");
      responseValues.put(setupPINResponseValue, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedFloatAttributeCallback
      implements ChipClusters.FloatAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(float value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "float");
      responseValues.put(setupPINResponseValue, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedDoubleAttributeCallback
      implements ChipClusters.DoubleAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(double value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "double");
      responseValues.put(setupPINResponseValue, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedDefaultClusterCallback
      implements DefaultClusterCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    // Parameters and list-adds here should be generated - refer to the template code that creates
    // each callback interface.
    @Override
    public void onSuccess() {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception e) {
      callback.onFailure(e);
    }
  }

  public static class DelegatedIdentifyClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.IdentifyCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIdentifyClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.IdentifyCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIdentifyClusterEventListAttributeCallback
      implements ChipClusters.IdentifyCluster.EventListAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIdentifyClusterAttributeListAttributeCallback
      implements ChipClusters.IdentifyCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGroupsClusterAddGroupResponseCallback
      implements ChipClusters.GroupsCluster.AddGroupResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Integer GroupID) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo GroupIDResponseValue = new CommandResponseInfo("GroupID", "Integer");
      responseValues.put(GroupIDResponseValue, GroupID);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedGroupsClusterViewGroupResponseCallback
      implements ChipClusters.GroupsCluster.ViewGroupResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Integer GroupID, String GroupName) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo GroupIDResponseValue = new CommandResponseInfo("GroupID", "Integer");
      responseValues.put(GroupIDResponseValue, GroupID);
      CommandResponseInfo GroupNameResponseValue = new CommandResponseInfo("GroupName", "String");
      responseValues.put(GroupNameResponseValue, GroupName);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedGroupsClusterGetGroupMembershipResponseCallback
      implements ChipClusters.GroupsCluster.GetGroupMembershipResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer Capacity, ArrayList<Integer> GroupList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo CapacityResponseValue = new CommandResponseInfo("Capacity", "Integer");
      responseValues.put(CapacityResponseValue, Capacity);
      // GroupList: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedGroupsClusterRemoveGroupResponseCallback
      implements ChipClusters.GroupsCluster.RemoveGroupResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Integer GroupID) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo GroupIDResponseValue = new CommandResponseInfo("GroupID", "Integer");
      responseValues.put(GroupIDResponseValue, GroupID);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedGroupsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.GroupsCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGroupsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.GroupsCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGroupsClusterEventListAttributeCallback
      implements ChipClusters.GroupsCluster.EventListAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGroupsClusterAttributeListAttributeCallback
      implements ChipClusters.GroupsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedScenesClusterAddSceneResponseCallback
      implements ChipClusters.ScenesCluster.AddSceneResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Integer GroupID, Integer SceneID) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo GroupIDResponseValue = new CommandResponseInfo("GroupID", "Integer");
      responseValues.put(GroupIDResponseValue, GroupID);
      CommandResponseInfo SceneIDResponseValue = new CommandResponseInfo("SceneID", "Integer");
      responseValues.put(SceneIDResponseValue, SceneID);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedScenesClusterViewSceneResponseCallback
      implements ChipClusters.ScenesCluster.ViewSceneResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer Status,
        Integer GroupID,
        Integer SceneID,
        Optional<Integer> TransitionTime,
        Optional<String> SceneName,
        Optional<ArrayList<ChipStructs.ScenesClusterExtensionFieldSet>> ExtensionFieldSets) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo GroupIDResponseValue = new CommandResponseInfo("GroupID", "Integer");
      responseValues.put(GroupIDResponseValue, GroupID);
      CommandResponseInfo SceneIDResponseValue = new CommandResponseInfo("SceneID", "Integer");
      responseValues.put(SceneIDResponseValue, SceneID);
      CommandResponseInfo TransitionTimeResponseValue =
          new CommandResponseInfo("TransitionTime", "Optional<Integer>");
      responseValues.put(TransitionTimeResponseValue, TransitionTime);
      CommandResponseInfo SceneNameResponseValue =
          new CommandResponseInfo("SceneName", "Optional<String>");
      responseValues.put(SceneNameResponseValue, SceneName);
      // ExtensionFieldSets: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedScenesClusterRemoveSceneResponseCallback
      implements ChipClusters.ScenesCluster.RemoveSceneResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Integer GroupID, Integer SceneID) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo GroupIDResponseValue = new CommandResponseInfo("GroupID", "Integer");
      responseValues.put(GroupIDResponseValue, GroupID);
      CommandResponseInfo SceneIDResponseValue = new CommandResponseInfo("SceneID", "Integer");
      responseValues.put(SceneIDResponseValue, SceneID);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedScenesClusterRemoveAllScenesResponseCallback
      implements ChipClusters.ScenesCluster.RemoveAllScenesResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Integer GroupID) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo GroupIDResponseValue = new CommandResponseInfo("GroupID", "Integer");
      responseValues.put(GroupIDResponseValue, GroupID);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedScenesClusterStoreSceneResponseCallback
      implements ChipClusters.ScenesCluster.StoreSceneResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Integer GroupID, Integer SceneID) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo GroupIDResponseValue = new CommandResponseInfo("GroupID", "Integer");
      responseValues.put(GroupIDResponseValue, GroupID);
      CommandResponseInfo SceneIDResponseValue = new CommandResponseInfo("SceneID", "Integer");
      responseValues.put(SceneIDResponseValue, SceneID);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedScenesClusterGetSceneMembershipResponseCallback
      implements ChipClusters.ScenesCluster.GetSceneMembershipResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer Status,
        @Nullable Integer Capacity,
        Integer GroupID,
        Optional<ArrayList<Integer>> SceneList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo CapacityResponseValue = new CommandResponseInfo("Capacity", "Integer");
      responseValues.put(CapacityResponseValue, Capacity);
      CommandResponseInfo GroupIDResponseValue = new CommandResponseInfo("GroupID", "Integer");
      responseValues.put(GroupIDResponseValue, GroupID);
      // SceneList: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedScenesClusterLastConfiguredByAttributeCallback
      implements ChipClusters.ScenesCluster.LastConfiguredByAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedScenesClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ScenesCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedScenesClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ScenesCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedScenesClusterEventListAttributeCallback
      implements ChipClusters.ScenesCluster.EventListAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedScenesClusterAttributeListAttributeCallback
      implements ChipClusters.ScenesCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOnOffClusterStartUpOnOffAttributeCallback
      implements ChipClusters.OnOffCluster.StartUpOnOffAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOnOffClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.OnOffCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOnOffClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.OnOffCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOnOffClusterEventListAttributeCallback
      implements ChipClusters.OnOffCluster.EventListAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOnOffClusterAttributeListAttributeCallback
      implements ChipClusters.OnOffCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOnOffSwitchConfigurationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.OnOffSwitchConfigurationCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOnOffSwitchConfigurationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.OnOffSwitchConfigurationCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOnOffSwitchConfigurationClusterEventListAttributeCallback
      implements ChipClusters.OnOffSwitchConfigurationCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOnOffSwitchConfigurationClusterAttributeListAttributeCallback
      implements ChipClusters.OnOffSwitchConfigurationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLevelControlClusterCurrentLevelAttributeCallback
      implements ChipClusters.LevelControlCluster.CurrentLevelAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLevelControlClusterOnLevelAttributeCallback
      implements ChipClusters.LevelControlCluster.OnLevelAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLevelControlClusterOnTransitionTimeAttributeCallback
      implements ChipClusters.LevelControlCluster.OnTransitionTimeAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLevelControlClusterOffTransitionTimeAttributeCallback
      implements ChipClusters.LevelControlCluster.OffTransitionTimeAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLevelControlClusterDefaultMoveRateAttributeCallback
      implements ChipClusters.LevelControlCluster.DefaultMoveRateAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLevelControlClusterStartUpCurrentLevelAttributeCallback
      implements ChipClusters.LevelControlCluster.StartUpCurrentLevelAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLevelControlClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.LevelControlCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLevelControlClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.LevelControlCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLevelControlClusterEventListAttributeCallback
      implements ChipClusters.LevelControlCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLevelControlClusterAttributeListAttributeCallback
      implements ChipClusters.LevelControlCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBinaryInputBasicClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BinaryInputBasicCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBinaryInputBasicClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BinaryInputBasicCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBinaryInputBasicClusterEventListAttributeCallback
      implements ChipClusters.BinaryInputBasicCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBinaryInputBasicClusterAttributeListAttributeCallback
      implements ChipClusters.BinaryInputBasicCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPulseWidthModulationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.PulseWidthModulationCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPulseWidthModulationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.PulseWidthModulationCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPulseWidthModulationClusterEventListAttributeCallback
      implements ChipClusters.PulseWidthModulationCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPulseWidthModulationClusterAttributeListAttributeCallback
      implements ChipClusters.PulseWidthModulationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDescriptorClusterDeviceTypeListAttributeCallback
      implements ChipClusters.DescriptorCluster.DeviceTypeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.DescriptorClusterDeviceTypeStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.DescriptorClusterDeviceTypeStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDescriptorClusterServerListAttributeCallback
      implements ChipClusters.DescriptorCluster.ServerListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDescriptorClusterClientListAttributeCallback
      implements ChipClusters.DescriptorCluster.ClientListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDescriptorClusterPartsListAttributeCallback
      implements ChipClusters.DescriptorCluster.PartsListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDescriptorClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.DescriptorCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDescriptorClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.DescriptorCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDescriptorClusterEventListAttributeCallback
      implements ChipClusters.DescriptorCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDescriptorClusterAttributeListAttributeCallback
      implements ChipClusters.DescriptorCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBindingClusterBindingAttributeCallback
      implements ChipClusters.BindingCluster.BindingAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.BindingClusterTargetStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<ChipStructs.BindingClusterTargetStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBindingClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BindingCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBindingClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BindingCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBindingClusterEventListAttributeCallback
      implements ChipClusters.BindingCluster.EventListAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBindingClusterAttributeListAttributeCallback
      implements ChipClusters.BindingCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccessControlClusterAclAttributeCallback
      implements ChipClusters.AccessControlCluster.AclAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        List<ChipStructs.AccessControlClusterAccessControlEntryStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.AccessControlClusterAccessControlEntryStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccessControlClusterExtensionAttributeCallback
      implements ChipClusters.AccessControlCluster.ExtensionAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        List<ChipStructs.AccessControlClusterAccessControlExtensionStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.AccessControlClusterAccessControlExtensionStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccessControlClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.AccessControlCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccessControlClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.AccessControlCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccessControlClusterEventListAttributeCallback
      implements ChipClusters.AccessControlCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccessControlClusterAttributeListAttributeCallback
      implements ChipClusters.AccessControlCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedActionsClusterActionListAttributeCallback
      implements ChipClusters.ActionsCluster.ActionListAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.ActionsClusterActionStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<ChipStructs.ActionsClusterActionStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedActionsClusterEndpointListsAttributeCallback
      implements ChipClusters.ActionsCluster.EndpointListsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.ActionsClusterEndpointListStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.ActionsClusterEndpointListStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedActionsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ActionsCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedActionsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ActionsCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedActionsClusterEventListAttributeCallback
      implements ChipClusters.ActionsCluster.EventListAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedActionsClusterAttributeListAttributeCallback
      implements ChipClusters.ActionsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBasicInformationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BasicInformationCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBasicInformationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BasicInformationCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBasicInformationClusterEventListAttributeCallback
      implements ChipClusters.BasicInformationCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBasicInformationClusterAttributeListAttributeCallback
      implements ChipClusters.BasicInformationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOtaSoftwareUpdateProviderClusterQueryImageResponseCallback
      implements ChipClusters.OtaSoftwareUpdateProviderCluster.QueryImageResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer Status,
        Optional<Long> DelayedActionTime,
        Optional<String> ImageURI,
        Optional<Long> SoftwareVersion,
        Optional<String> SoftwareVersionString,
        Optional<byte[]> UpdateToken,
        Optional<Boolean> UserConsentNeeded,
        Optional<byte[]> MetadataForRequestor) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo DelayedActionTimeResponseValue =
          new CommandResponseInfo("DelayedActionTime", "Optional<Long>");
      responseValues.put(DelayedActionTimeResponseValue, DelayedActionTime);
      CommandResponseInfo ImageURIResponseValue =
          new CommandResponseInfo("ImageURI", "Optional<String>");
      responseValues.put(ImageURIResponseValue, ImageURI);
      CommandResponseInfo SoftwareVersionResponseValue =
          new CommandResponseInfo("SoftwareVersion", "Optional<Long>");
      responseValues.put(SoftwareVersionResponseValue, SoftwareVersion);
      CommandResponseInfo SoftwareVersionStringResponseValue =
          new CommandResponseInfo("SoftwareVersionString", "Optional<String>");
      responseValues.put(SoftwareVersionStringResponseValue, SoftwareVersionString);
      CommandResponseInfo UpdateTokenResponseValue =
          new CommandResponseInfo("UpdateToken", "Optional<byte[]>");
      responseValues.put(UpdateTokenResponseValue, UpdateToken);
      CommandResponseInfo UserConsentNeededResponseValue =
          new CommandResponseInfo("UserConsentNeeded", "Optional<Boolean>");
      responseValues.put(UserConsentNeededResponseValue, UserConsentNeeded);
      CommandResponseInfo MetadataForRequestorResponseValue =
          new CommandResponseInfo("MetadataForRequestor", "Optional<byte[]>");
      responseValues.put(MetadataForRequestorResponseValue, MetadataForRequestor);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedOtaSoftwareUpdateProviderClusterApplyUpdateResponseCallback
      implements ChipClusters.OtaSoftwareUpdateProviderCluster.ApplyUpdateResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Action, Long DelayedActionTime) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo ActionResponseValue = new CommandResponseInfo("Action", "Integer");
      responseValues.put(ActionResponseValue, Action);
      CommandResponseInfo DelayedActionTimeResponseValue =
          new CommandResponseInfo("DelayedActionTime", "Long");
      responseValues.put(DelayedActionTimeResponseValue, DelayedActionTime);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedOtaSoftwareUpdateProviderClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.OtaSoftwareUpdateProviderCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOtaSoftwareUpdateProviderClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.OtaSoftwareUpdateProviderCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOtaSoftwareUpdateProviderClusterEventListAttributeCallback
      implements ChipClusters.OtaSoftwareUpdateProviderCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOtaSoftwareUpdateProviderClusterAttributeListAttributeCallback
      implements ChipClusters.OtaSoftwareUpdateProviderCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOtaSoftwareUpdateRequestorClusterDefaultOTAProvidersAttributeCallback
      implements ChipClusters.OtaSoftwareUpdateRequestorCluster
              .DefaultOTAProvidersAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        List<ChipStructs.OtaSoftwareUpdateRequestorClusterProviderLocation> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.OtaSoftwareUpdateRequestorClusterProviderLocation>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOtaSoftwareUpdateRequestorClusterUpdateStateProgressAttributeCallback
      implements ChipClusters.OtaSoftwareUpdateRequestorCluster
              .UpdateStateProgressAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedOtaSoftwareUpdateRequestorClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.OtaSoftwareUpdateRequestorCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOtaSoftwareUpdateRequestorClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.OtaSoftwareUpdateRequestorCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOtaSoftwareUpdateRequestorClusterEventListAttributeCallback
      implements ChipClusters.OtaSoftwareUpdateRequestorCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOtaSoftwareUpdateRequestorClusterAttributeListAttributeCallback
      implements ChipClusters.OtaSoftwareUpdateRequestorCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLocalizationConfigurationClusterSupportedLocalesAttributeCallback
      implements ChipClusters.LocalizationConfigurationCluster.SupportedLocalesAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<String> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<String>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLocalizationConfigurationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.LocalizationConfigurationCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLocalizationConfigurationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.LocalizationConfigurationCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLocalizationConfigurationClusterEventListAttributeCallback
      implements ChipClusters.LocalizationConfigurationCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLocalizationConfigurationClusterAttributeListAttributeCallback
      implements ChipClusters.LocalizationConfigurationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeFormatLocalizationClusterSupportedCalendarTypesAttributeCallback
      implements ChipClusters.TimeFormatLocalizationCluster.SupportedCalendarTypesAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeFormatLocalizationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.TimeFormatLocalizationCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeFormatLocalizationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.TimeFormatLocalizationCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeFormatLocalizationClusterEventListAttributeCallback
      implements ChipClusters.TimeFormatLocalizationCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeFormatLocalizationClusterAttributeListAttributeCallback
      implements ChipClusters.TimeFormatLocalizationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitLocalizationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.UnitLocalizationCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitLocalizationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.UnitLocalizationCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitLocalizationClusterEventListAttributeCallback
      implements ChipClusters.UnitLocalizationCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitLocalizationClusterAttributeListAttributeCallback
      implements ChipClusters.UnitLocalizationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceConfigurationClusterSourcesAttributeCallback
      implements ChipClusters.PowerSourceConfigurationCluster.SourcesAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceConfigurationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.PowerSourceConfigurationCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceConfigurationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.PowerSourceConfigurationCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceConfigurationClusterEventListAttributeCallback
      implements ChipClusters.PowerSourceConfigurationCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceConfigurationClusterAttributeListAttributeCallback
      implements ChipClusters.PowerSourceConfigurationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterWiredAssessedInputVoltageAttributeCallback
      implements ChipClusters.PowerSourceCluster.WiredAssessedInputVoltageAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterWiredAssessedInputFrequencyAttributeCallback
      implements ChipClusters.PowerSourceCluster.WiredAssessedInputFrequencyAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterWiredAssessedCurrentAttributeCallback
      implements ChipClusters.PowerSourceCluster.WiredAssessedCurrentAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterActiveWiredFaultsAttributeCallback
      implements ChipClusters.PowerSourceCluster.ActiveWiredFaultsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterBatVoltageAttributeCallback
      implements ChipClusters.PowerSourceCluster.BatVoltageAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterBatPercentRemainingAttributeCallback
      implements ChipClusters.PowerSourceCluster.BatPercentRemainingAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterBatTimeRemainingAttributeCallback
      implements ChipClusters.PowerSourceCluster.BatTimeRemainingAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterActiveBatFaultsAttributeCallback
      implements ChipClusters.PowerSourceCluster.ActiveBatFaultsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterBatTimeToFullChargeAttributeCallback
      implements ChipClusters.PowerSourceCluster.BatTimeToFullChargeAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterBatChargingCurrentAttributeCallback
      implements ChipClusters.PowerSourceCluster.BatChargingCurrentAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterActiveBatChargeFaultsAttributeCallback
      implements ChipClusters.PowerSourceCluster.ActiveBatChargeFaultsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.PowerSourceCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.PowerSourceCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterEventListAttributeCallback
      implements ChipClusters.PowerSourceCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPowerSourceClusterAttributeListAttributeCallback
      implements ChipClusters.PowerSourceCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralCommissioningClusterArmFailSafeResponseCallback
      implements ChipClusters.GeneralCommissioningCluster.ArmFailSafeResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer ErrorCode, String DebugText) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo ErrorCodeResponseValue = new CommandResponseInfo("ErrorCode", "Integer");
      responseValues.put(ErrorCodeResponseValue, ErrorCode);
      CommandResponseInfo DebugTextResponseValue = new CommandResponseInfo("DebugText", "String");
      responseValues.put(DebugTextResponseValue, DebugText);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedGeneralCommissioningClusterSetRegulatoryConfigResponseCallback
      implements ChipClusters.GeneralCommissioningCluster.SetRegulatoryConfigResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer ErrorCode, String DebugText) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo ErrorCodeResponseValue = new CommandResponseInfo("ErrorCode", "Integer");
      responseValues.put(ErrorCodeResponseValue, ErrorCode);
      CommandResponseInfo DebugTextResponseValue = new CommandResponseInfo("DebugText", "String");
      responseValues.put(DebugTextResponseValue, DebugText);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedGeneralCommissioningClusterCommissioningCompleteResponseCallback
      implements ChipClusters.GeneralCommissioningCluster.CommissioningCompleteResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer ErrorCode, String DebugText) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo ErrorCodeResponseValue = new CommandResponseInfo("ErrorCode", "Integer");
      responseValues.put(ErrorCodeResponseValue, ErrorCode);
      CommandResponseInfo DebugTextResponseValue = new CommandResponseInfo("DebugText", "String");
      responseValues.put(DebugTextResponseValue, DebugText);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedGeneralCommissioningClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.GeneralCommissioningCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralCommissioningClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.GeneralCommissioningCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralCommissioningClusterEventListAttributeCallback
      implements ChipClusters.GeneralCommissioningCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralCommissioningClusterAttributeListAttributeCallback
      implements ChipClusters.GeneralCommissioningCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedNetworkCommissioningClusterScanNetworksResponseCallback
      implements ChipClusters.NetworkCommissioningCluster.ScanNetworksResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer NetworkingStatus,
        Optional<String> DebugText,
        Optional<ArrayList<ChipStructs.NetworkCommissioningClusterWiFiInterfaceScanResult>>
            WiFiScanResults,
        Optional<ArrayList<ChipStructs.NetworkCommissioningClusterThreadInterfaceScanResult>>
            ThreadScanResults) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo NetworkingStatusResponseValue =
          new CommandResponseInfo("NetworkingStatus", "Integer");
      responseValues.put(NetworkingStatusResponseValue, NetworkingStatus);
      CommandResponseInfo DebugTextResponseValue =
          new CommandResponseInfo("DebugText", "Optional<String>");
      responseValues.put(DebugTextResponseValue, DebugText);
      // WiFiScanResults: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      // ThreadScanResults: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedNetworkCommissioningClusterNetworkConfigResponseCallback
      implements ChipClusters.NetworkCommissioningCluster.NetworkConfigResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer NetworkingStatus, Optional<String> DebugText, Optional<Integer> NetworkIndex) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo NetworkingStatusResponseValue =
          new CommandResponseInfo("NetworkingStatus", "Integer");
      responseValues.put(NetworkingStatusResponseValue, NetworkingStatus);
      CommandResponseInfo DebugTextResponseValue =
          new CommandResponseInfo("DebugText", "Optional<String>");
      responseValues.put(DebugTextResponseValue, DebugText);
      CommandResponseInfo NetworkIndexResponseValue =
          new CommandResponseInfo("NetworkIndex", "Optional<Integer>");
      responseValues.put(NetworkIndexResponseValue, NetworkIndex);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedNetworkCommissioningClusterConnectNetworkResponseCallback
      implements ChipClusters.NetworkCommissioningCluster.ConnectNetworkResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer NetworkingStatus, Optional<String> DebugText, @Nullable Long ErrorValue) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo NetworkingStatusResponseValue =
          new CommandResponseInfo("NetworkingStatus", "Integer");
      responseValues.put(NetworkingStatusResponseValue, NetworkingStatus);
      CommandResponseInfo DebugTextResponseValue =
          new CommandResponseInfo("DebugText", "Optional<String>");
      responseValues.put(DebugTextResponseValue, DebugText);
      CommandResponseInfo ErrorValueResponseValue = new CommandResponseInfo("ErrorValue", "Long");
      responseValues.put(ErrorValueResponseValue, ErrorValue);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedNetworkCommissioningClusterNetworksAttributeCallback
      implements ChipClusters.NetworkCommissioningCluster.NetworksAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.NetworkCommissioningClusterNetworkInfo> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.NetworkCommissioningClusterNetworkInfo>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedNetworkCommissioningClusterLastNetworkingStatusAttributeCallback
      implements ChipClusters.NetworkCommissioningCluster.LastNetworkingStatusAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedNetworkCommissioningClusterLastNetworkIDAttributeCallback
      implements ChipClusters.NetworkCommissioningCluster.LastNetworkIDAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable byte[] value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "byte[]");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedNetworkCommissioningClusterLastConnectErrorValueAttributeCallback
      implements ChipClusters.NetworkCommissioningCluster.LastConnectErrorValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedNetworkCommissioningClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.NetworkCommissioningCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedNetworkCommissioningClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.NetworkCommissioningCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedNetworkCommissioningClusterEventListAttributeCallback
      implements ChipClusters.NetworkCommissioningCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedNetworkCommissioningClusterAttributeListAttributeCallback
      implements ChipClusters.NetworkCommissioningCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDiagnosticLogsClusterRetrieveLogsResponseCallback
      implements ChipClusters.DiagnosticLogsCluster.RetrieveLogsResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer Status,
        byte[] LogContent,
        Optional<Long> UTCTimeStamp,
        Optional<Long> TimeSinceBoot) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo LogContentResponseValue = new CommandResponseInfo("LogContent", "byte[]");
      responseValues.put(LogContentResponseValue, LogContent);
      CommandResponseInfo UTCTimeStampResponseValue =
          new CommandResponseInfo("UTCTimeStamp", "Optional<Long>");
      responseValues.put(UTCTimeStampResponseValue, UTCTimeStamp);
      CommandResponseInfo TimeSinceBootResponseValue =
          new CommandResponseInfo("TimeSinceBoot", "Optional<Long>");
      responseValues.put(TimeSinceBootResponseValue, TimeSinceBoot);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedDiagnosticLogsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.DiagnosticLogsCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDiagnosticLogsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.DiagnosticLogsCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDiagnosticLogsClusterEventListAttributeCallback
      implements ChipClusters.DiagnosticLogsCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDiagnosticLogsClusterAttributeListAttributeCallback
      implements ChipClusters.DiagnosticLogsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralDiagnosticsClusterNetworkInterfacesAttributeCallback
      implements ChipClusters.GeneralDiagnosticsCluster.NetworkInterfacesAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.GeneralDiagnosticsClusterNetworkInterface> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.GeneralDiagnosticsClusterNetworkInterface>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralDiagnosticsClusterActiveHardwareFaultsAttributeCallback
      implements ChipClusters.GeneralDiagnosticsCluster.ActiveHardwareFaultsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralDiagnosticsClusterActiveRadioFaultsAttributeCallback
      implements ChipClusters.GeneralDiagnosticsCluster.ActiveRadioFaultsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralDiagnosticsClusterActiveNetworkFaultsAttributeCallback
      implements ChipClusters.GeneralDiagnosticsCluster.ActiveNetworkFaultsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralDiagnosticsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.GeneralDiagnosticsCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralDiagnosticsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.GeneralDiagnosticsCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralDiagnosticsClusterEventListAttributeCallback
      implements ChipClusters.GeneralDiagnosticsCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGeneralDiagnosticsClusterAttributeListAttributeCallback
      implements ChipClusters.GeneralDiagnosticsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSoftwareDiagnosticsClusterThreadMetricsAttributeCallback
      implements ChipClusters.SoftwareDiagnosticsCluster.ThreadMetricsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        List<ChipStructs.SoftwareDiagnosticsClusterThreadMetricsStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.SoftwareDiagnosticsClusterThreadMetricsStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSoftwareDiagnosticsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.SoftwareDiagnosticsCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSoftwareDiagnosticsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.SoftwareDiagnosticsCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSoftwareDiagnosticsClusterEventListAttributeCallback
      implements ChipClusters.SoftwareDiagnosticsCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSoftwareDiagnosticsClusterAttributeListAttributeCallback
      implements ChipClusters.SoftwareDiagnosticsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterChannelAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.ChannelAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.RoutingRoleAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterNetworkNameAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.NetworkNameAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable String value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "String");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterPanIdAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.PanIdAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterExtendedPanIdAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.ExtendedPanIdAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterMeshLocalPrefixAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.MeshLocalPrefixAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable byte[] value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "byte[]");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterNeighborTableAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.NeighborTableAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        List<ChipStructs.ThreadNetworkDiagnosticsClusterNeighborTable> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.ThreadNetworkDiagnosticsClusterNeighborTable>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterRouteTableAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.RouteTableAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.ThreadNetworkDiagnosticsClusterRouteTable> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.ThreadNetworkDiagnosticsClusterRouteTable>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterPartitionIdAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.PartitionIdAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterWeightingAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.WeightingAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterDataVersionAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.DataVersionAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterStableDataVersionAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.StableDataVersionAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterLeaderRouterIdAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.LeaderRouterIdAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterActiveTimestampAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.ActiveTimestampAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterPendingTimestampAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.PendingTimestampAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterDelayAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.DelayAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterChannelPage0MaskAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.ChannelPage0MaskAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable byte[] value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "byte[]");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedThreadNetworkDiagnosticsClusterActiveNetworkFaultsListAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster
              .ActiveNetworkFaultsListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterEventListAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThreadNetworkDiagnosticsClusterAttributeListAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterBssidAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.BssidAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable byte[] value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "byte[]");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterSecurityTypeAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.SecurityTypeAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterWiFiVersionAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.WiFiVersionAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterChannelNumberAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.ChannelNumberAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterRssiAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.RssiAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterBeaconLostCountAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.BeaconLostCountAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterBeaconRxCountAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.BeaconRxCountAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterPacketMulticastRxCountAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.PacketMulticastRxCountAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterPacketMulticastTxCountAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.PacketMulticastTxCountAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterPacketUnicastRxCountAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.PacketUnicastRxCountAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterPacketUnicastTxCountAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.PacketUnicastTxCountAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterCurrentMaxRateAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.CurrentMaxRateAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterOverrunCountAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.OverrunCountAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterEventListAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWiFiNetworkDiagnosticsClusterAttributeListAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedEthernetNetworkDiagnosticsClusterPHYRateAttributeCallback
      implements ChipClusters.EthernetNetworkDiagnosticsCluster.PHYRateAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedEthernetNetworkDiagnosticsClusterFullDuplexAttributeCallback
      implements ChipClusters.EthernetNetworkDiagnosticsCluster.FullDuplexAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Boolean value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Boolean");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedEthernetNetworkDiagnosticsClusterCarrierDetectAttributeCallback
      implements ChipClusters.EthernetNetworkDiagnosticsCluster.CarrierDetectAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Boolean value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Boolean");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedEthernetNetworkDiagnosticsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.EthernetNetworkDiagnosticsCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedEthernetNetworkDiagnosticsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.EthernetNetworkDiagnosticsCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedEthernetNetworkDiagnosticsClusterEventListAttributeCallback
      implements ChipClusters.EthernetNetworkDiagnosticsCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedEthernetNetworkDiagnosticsClusterAttributeListAttributeCallback
      implements ChipClusters.EthernetNetworkDiagnosticsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeSynchronizationClusterUTCTimeAttributeCallback
      implements ChipClusters.TimeSynchronizationCluster.UTCTimeAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeSynchronizationClusterDefaultNTPAttributeCallback
      implements ChipClusters.TimeSynchronizationCluster.DefaultNTPAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable String value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "String");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeSynchronizationClusterTimeZoneAttributeCallback
      implements ChipClusters.TimeSynchronizationCluster.TimeZoneAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.TimeSynchronizationClusterTimeZoneStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.TimeSynchronizationClusterTimeZoneStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeSynchronizationClusterDSTOffsetAttributeCallback
      implements ChipClusters.TimeSynchronizationCluster.DSTOffsetAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.TimeSynchronizationClusterDSTOffsetStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.TimeSynchronizationClusterDSTOffsetStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeSynchronizationClusterLocalTimeAttributeCallback
      implements ChipClusters.TimeSynchronizationCluster.LocalTimeAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeSynchronizationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.TimeSynchronizationCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeSynchronizationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.TimeSynchronizationCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeSynchronizationClusterEventListAttributeCallback
      implements ChipClusters.TimeSynchronizationCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTimeSynchronizationClusterAttributeListAttributeCallback
      implements ChipClusters.TimeSynchronizationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedBridgedDeviceBasicInformationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BridgedDeviceBasicInformationCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedBridgedDeviceBasicInformationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BridgedDeviceBasicInformationCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBridgedDeviceBasicInformationClusterEventListAttributeCallback
      implements ChipClusters.BridgedDeviceBasicInformationCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBridgedDeviceBasicInformationClusterAttributeListAttributeCallback
      implements ChipClusters.BridgedDeviceBasicInformationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSwitchClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.SwitchCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSwitchClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.SwitchCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSwitchClusterEventListAttributeCallback
      implements ChipClusters.SwitchCluster.EventListAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSwitchClusterAttributeListAttributeCallback
      implements ChipClusters.SwitchCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAdministratorCommissioningClusterAdminFabricIndexAttributeCallback
      implements ChipClusters.AdministratorCommissioningCluster.AdminFabricIndexAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAdministratorCommissioningClusterAdminVendorIdAttributeCallback
      implements ChipClusters.AdministratorCommissioningCluster.AdminVendorIdAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedAdministratorCommissioningClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.AdministratorCommissioningCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAdministratorCommissioningClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.AdministratorCommissioningCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAdministratorCommissioningClusterEventListAttributeCallback
      implements ChipClusters.AdministratorCommissioningCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAdministratorCommissioningClusterAttributeListAttributeCallback
      implements ChipClusters.AdministratorCommissioningCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOperationalCredentialsClusterAttestationResponseCallback
      implements ChipClusters.OperationalCredentialsCluster.AttestationResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(byte[] AttestationElements, byte[] AttestationSignature) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo AttestationElementsResponseValue =
          new CommandResponseInfo("AttestationElements", "byte[]");
      responseValues.put(AttestationElementsResponseValue, AttestationElements);
      CommandResponseInfo AttestationSignatureResponseValue =
          new CommandResponseInfo("AttestationSignature", "byte[]");
      responseValues.put(AttestationSignatureResponseValue, AttestationSignature);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedOperationalCredentialsClusterCertificateChainResponseCallback
      implements ChipClusters.OperationalCredentialsCluster.CertificateChainResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(byte[] Certificate) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo CertificateResponseValue =
          new CommandResponseInfo("Certificate", "byte[]");
      responseValues.put(CertificateResponseValue, Certificate);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedOperationalCredentialsClusterCSRResponseCallback
      implements ChipClusters.OperationalCredentialsCluster.CSRResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(byte[] NOCSRElements, byte[] AttestationSignature) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo NOCSRElementsResponseValue =
          new CommandResponseInfo("NOCSRElements", "byte[]");
      responseValues.put(NOCSRElementsResponseValue, NOCSRElements);
      CommandResponseInfo AttestationSignatureResponseValue =
          new CommandResponseInfo("AttestationSignature", "byte[]");
      responseValues.put(AttestationSignatureResponseValue, AttestationSignature);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedOperationalCredentialsClusterNOCResponseCallback
      implements ChipClusters.OperationalCredentialsCluster.NOCResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer StatusCode, Optional<Integer> FabricIndex, Optional<String> DebugText) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusCodeResponseValue =
          new CommandResponseInfo("StatusCode", "Integer");
      responseValues.put(StatusCodeResponseValue, StatusCode);
      CommandResponseInfo FabricIndexResponseValue =
          new CommandResponseInfo("FabricIndex", "Optional<Integer>");
      responseValues.put(FabricIndexResponseValue, FabricIndex);
      CommandResponseInfo DebugTextResponseValue =
          new CommandResponseInfo("DebugText", "Optional<String>");
      responseValues.put(DebugTextResponseValue, DebugText);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedOperationalCredentialsClusterNOCsAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster.NOCsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.OperationalCredentialsClusterNOCStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.OperationalCredentialsClusterNOCStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOperationalCredentialsClusterFabricsAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster.FabricsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        List<ChipStructs.OperationalCredentialsClusterFabricDescriptorStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.OperationalCredentialsClusterFabricDescriptorStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOperationalCredentialsClusterTrustedRootCertificatesAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster
              .TrustedRootCertificatesAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<byte[]> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<byte[]>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOperationalCredentialsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOperationalCredentialsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOperationalCredentialsClusterEventListAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOperationalCredentialsClusterAttributeListAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGroupKeyManagementClusterKeySetReadResponseCallback
      implements ChipClusters.GroupKeyManagementCluster.KeySetReadResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(ChipStructs.GroupKeyManagementClusterGroupKeySetStruct GroupKeySet) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      // GroupKeySet: Struct GroupKeySetStruct
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedGroupKeyManagementClusterKeySetReadAllIndicesResponseCallback
      implements ChipClusters.GroupKeyManagementCluster.KeySetReadAllIndicesResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(ArrayList<Integer> GroupKeySetIDs) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      // GroupKeySetIDs: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedGroupKeyManagementClusterGroupKeyMapAttributeCallback
      implements ChipClusters.GroupKeyManagementCluster.GroupKeyMapAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.GroupKeyManagementClusterGroupKeyMapStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.GroupKeyManagementClusterGroupKeyMapStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGroupKeyManagementClusterGroupTableAttributeCallback
      implements ChipClusters.GroupKeyManagementCluster.GroupTableAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.GroupKeyManagementClusterGroupInfoMapStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.GroupKeyManagementClusterGroupInfoMapStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGroupKeyManagementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.GroupKeyManagementCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGroupKeyManagementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.GroupKeyManagementCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGroupKeyManagementClusterEventListAttributeCallback
      implements ChipClusters.GroupKeyManagementCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGroupKeyManagementClusterAttributeListAttributeCallback
      implements ChipClusters.GroupKeyManagementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFixedLabelClusterLabelListAttributeCallback
      implements ChipClusters.FixedLabelCluster.LabelListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.FixedLabelClusterLabelStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<ChipStructs.FixedLabelClusterLabelStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFixedLabelClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.FixedLabelCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFixedLabelClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.FixedLabelCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFixedLabelClusterEventListAttributeCallback
      implements ChipClusters.FixedLabelCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFixedLabelClusterAttributeListAttributeCallback
      implements ChipClusters.FixedLabelCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUserLabelClusterLabelListAttributeCallback
      implements ChipClusters.UserLabelCluster.LabelListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.UserLabelClusterLabelStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<ChipStructs.UserLabelClusterLabelStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUserLabelClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.UserLabelCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUserLabelClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.UserLabelCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUserLabelClusterEventListAttributeCallback
      implements ChipClusters.UserLabelCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUserLabelClusterAttributeListAttributeCallback
      implements ChipClusters.UserLabelCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyConfigurationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ProxyConfigurationCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyConfigurationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ProxyConfigurationCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyConfigurationClusterEventListAttributeCallback
      implements ChipClusters.ProxyConfigurationCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyConfigurationClusterAttributeListAttributeCallback
      implements ChipClusters.ProxyConfigurationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyDiscoveryClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ProxyDiscoveryCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyDiscoveryClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ProxyDiscoveryCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyDiscoveryClusterEventListAttributeCallback
      implements ChipClusters.ProxyDiscoveryCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyDiscoveryClusterAttributeListAttributeCallback
      implements ChipClusters.ProxyDiscoveryCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyValidClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ProxyValidCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyValidClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ProxyValidCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyValidClusterEventListAttributeCallback
      implements ChipClusters.ProxyValidCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedProxyValidClusterAttributeListAttributeCallback
      implements ChipClusters.ProxyValidCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBooleanStateClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BooleanStateCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBooleanStateClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BooleanStateCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBooleanStateClusterEventListAttributeCallback
      implements ChipClusters.BooleanStateCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBooleanStateClusterAttributeListAttributeCallback
      implements ChipClusters.BooleanStateCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIcdManagementClusterRegisterClientResponseCallback
      implements ChipClusters.IcdManagementCluster.RegisterClientResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Long ICDCounter) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo ICDCounterResponseValue = new CommandResponseInfo("ICDCounter", "Long");
      responseValues.put(ICDCounterResponseValue, ICDCounter);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedIcdManagementClusterRegisteredClientsAttributeCallback
      implements ChipClusters.IcdManagementCluster.RegisteredClientsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        List<ChipStructs.IcdManagementClusterMonitoringRegistrationStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.IcdManagementClusterMonitoringRegistrationStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIcdManagementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.IcdManagementCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIcdManagementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.IcdManagementCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIcdManagementClusterEventListAttributeCallback
      implements ChipClusters.IcdManagementCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIcdManagementClusterAttributeListAttributeCallback
      implements ChipClusters.IcdManagementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedModeSelectClusterStandardNamespaceAttributeCallback
      implements ChipClusters.ModeSelectCluster.StandardNamespaceAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedModeSelectClusterSupportedModesAttributeCallback
      implements ChipClusters.ModeSelectCluster.SupportedModesAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.ModeSelectClusterModeOptionStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.ModeSelectClusterModeOptionStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedModeSelectClusterStartUpModeAttributeCallback
      implements ChipClusters.ModeSelectCluster.StartUpModeAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedModeSelectClusterOnModeAttributeCallback
      implements ChipClusters.ModeSelectCluster.OnModeAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedModeSelectClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ModeSelectCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedModeSelectClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ModeSelectCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedModeSelectClusterEventListAttributeCallback
      implements ChipClusters.ModeSelectCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedModeSelectClusterAttributeListAttributeCallback
      implements ChipClusters.ModeSelectCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureControlClusterSupportedTemperatureLevelsAttributeCallback
      implements ChipClusters.TemperatureControlCluster.SupportedTemperatureLevelsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        List<ChipStructs.TemperatureControlClusterTemperatureLevelStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.TemperatureControlClusterTemperatureLevelStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureControlClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.TemperatureControlCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureControlClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.TemperatureControlCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureControlClusterEventListAttributeCallback
      implements ChipClusters.TemperatureControlCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureControlClusterAttributeListAttributeCallback
      implements ChipClusters.TemperatureControlCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedRefrigeratorAlarmClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.RefrigeratorAlarmCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedRefrigeratorAlarmClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.RefrigeratorAlarmCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedRefrigeratorAlarmClusterEventListAttributeCallback
      implements ChipClusters.RefrigeratorAlarmCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedRefrigeratorAlarmClusterAttributeListAttributeCallback
      implements ChipClusters.RefrigeratorAlarmCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAirQualityClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.AirQualityCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAirQualityClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.AirQualityCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAirQualityClusterEventListAttributeCallback
      implements ChipClusters.AirQualityCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAirQualityClusterAttributeListAttributeCallback
      implements ChipClusters.AirQualityCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSmokeCoAlarmClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.SmokeCoAlarmCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSmokeCoAlarmClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.SmokeCoAlarmCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSmokeCoAlarmClusterEventListAttributeCallback
      implements ChipClusters.SmokeCoAlarmCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSmokeCoAlarmClusterAttributeListAttributeCallback
      implements ChipClusters.SmokeCoAlarmCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedHepaFilterMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.HepaFilterMonitoringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedHepaFilterMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.HepaFilterMonitoringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedHepaFilterMonitoringClusterEventListAttributeCallback
      implements ChipClusters.HepaFilterMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedHepaFilterMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.HepaFilterMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedActivatedCarbonFilterMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ActivatedCarbonFilterMonitoringCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedActivatedCarbonFilterMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ActivatedCarbonFilterMonitoringCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedActivatedCarbonFilterMonitoringClusterEventListAttributeCallback
      implements ChipClusters.ActivatedCarbonFilterMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedActivatedCarbonFilterMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.ActivatedCarbonFilterMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedCeramicFilterMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.CeramicFilterMonitoringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedCeramicFilterMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.CeramicFilterMonitoringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedCeramicFilterMonitoringClusterEventListAttributeCallback
      implements ChipClusters.CeramicFilterMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedCeramicFilterMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.CeramicFilterMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedElectrostaticFilterMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ElectrostaticFilterMonitoringCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedElectrostaticFilterMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ElectrostaticFilterMonitoringCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedElectrostaticFilterMonitoringClusterEventListAttributeCallback
      implements ChipClusters.ElectrostaticFilterMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedElectrostaticFilterMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.ElectrostaticFilterMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUvFilterMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.UvFilterMonitoringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUvFilterMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.UvFilterMonitoringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUvFilterMonitoringClusterEventListAttributeCallback
      implements ChipClusters.UvFilterMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUvFilterMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.UvFilterMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIonizingFilterMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.IonizingFilterMonitoringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIonizingFilterMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.IonizingFilterMonitoringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIonizingFilterMonitoringClusterEventListAttributeCallback
      implements ChipClusters.IonizingFilterMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIonizingFilterMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.IonizingFilterMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedZeoliteFilterMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ZeoliteFilterMonitoringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedZeoliteFilterMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ZeoliteFilterMonitoringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedZeoliteFilterMonitoringClusterEventListAttributeCallback
      implements ChipClusters.ZeoliteFilterMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedZeoliteFilterMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.ZeoliteFilterMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOzoneFilterMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.OzoneFilterMonitoringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOzoneFilterMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.OzoneFilterMonitoringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOzoneFilterMonitoringClusterEventListAttributeCallback
      implements ChipClusters.OzoneFilterMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOzoneFilterMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.OzoneFilterMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWaterTankMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.WaterTankMonitoringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWaterTankMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.WaterTankMonitoringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWaterTankMonitoringClusterEventListAttributeCallback
      implements ChipClusters.WaterTankMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWaterTankMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.WaterTankMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFuelTankMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.FuelTankMonitoringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFuelTankMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.FuelTankMonitoringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFuelTankMonitoringClusterEventListAttributeCallback
      implements ChipClusters.FuelTankMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFuelTankMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.FuelTankMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedInkCartridgeMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.InkCartridgeMonitoringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedInkCartridgeMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.InkCartridgeMonitoringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedInkCartridgeMonitoringClusterEventListAttributeCallback
      implements ChipClusters.InkCartridgeMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedInkCartridgeMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.InkCartridgeMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTonerCartridgeMonitoringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.TonerCartridgeMonitoringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTonerCartridgeMonitoringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.TonerCartridgeMonitoringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTonerCartridgeMonitoringClusterEventListAttributeCallback
      implements ChipClusters.TonerCartridgeMonitoringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTonerCartridgeMonitoringClusterAttributeListAttributeCallback
      implements ChipClusters.TonerCartridgeMonitoringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDoorLockClusterGetWeekDayScheduleResponseCallback
      implements ChipClusters.DoorLockCluster.GetWeekDayScheduleResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer WeekDayIndex,
        Integer UserIndex,
        Integer Status,
        Optional<Integer> DaysMask,
        Optional<Integer> StartHour,
        Optional<Integer> StartMinute,
        Optional<Integer> EndHour,
        Optional<Integer> EndMinute) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo WeekDayIndexResponseValue =
          new CommandResponseInfo("WeekDayIndex", "Integer");
      responseValues.put(WeekDayIndexResponseValue, WeekDayIndex);
      CommandResponseInfo UserIndexResponseValue = new CommandResponseInfo("UserIndex", "Integer");
      responseValues.put(UserIndexResponseValue, UserIndex);
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo DaysMaskResponseValue =
          new CommandResponseInfo("DaysMask", "Optional<Integer>");
      responseValues.put(DaysMaskResponseValue, DaysMask);
      CommandResponseInfo StartHourResponseValue =
          new CommandResponseInfo("StartHour", "Optional<Integer>");
      responseValues.put(StartHourResponseValue, StartHour);
      CommandResponseInfo StartMinuteResponseValue =
          new CommandResponseInfo("StartMinute", "Optional<Integer>");
      responseValues.put(StartMinuteResponseValue, StartMinute);
      CommandResponseInfo EndHourResponseValue =
          new CommandResponseInfo("EndHour", "Optional<Integer>");
      responseValues.put(EndHourResponseValue, EndHour);
      CommandResponseInfo EndMinuteResponseValue =
          new CommandResponseInfo("EndMinute", "Optional<Integer>");
      responseValues.put(EndMinuteResponseValue, EndMinute);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedDoorLockClusterGetYearDayScheduleResponseCallback
      implements ChipClusters.DoorLockCluster.GetYearDayScheduleResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer YearDayIndex,
        Integer UserIndex,
        Integer Status,
        Optional<Long> LocalStartTime,
        Optional<Long> LocalEndTime) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo YearDayIndexResponseValue =
          new CommandResponseInfo("YearDayIndex", "Integer");
      responseValues.put(YearDayIndexResponseValue, YearDayIndex);
      CommandResponseInfo UserIndexResponseValue = new CommandResponseInfo("UserIndex", "Integer");
      responseValues.put(UserIndexResponseValue, UserIndex);
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo LocalStartTimeResponseValue =
          new CommandResponseInfo("LocalStartTime", "Optional<Long>");
      responseValues.put(LocalStartTimeResponseValue, LocalStartTime);
      CommandResponseInfo LocalEndTimeResponseValue =
          new CommandResponseInfo("LocalEndTime", "Optional<Long>");
      responseValues.put(LocalEndTimeResponseValue, LocalEndTime);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedDoorLockClusterGetHolidayScheduleResponseCallback
      implements ChipClusters.DoorLockCluster.GetHolidayScheduleResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer HolidayIndex,
        Integer Status,
        Optional<Long> LocalStartTime,
        Optional<Long> LocalEndTime,
        Optional<Integer> OperatingMode) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo HolidayIndexResponseValue =
          new CommandResponseInfo("HolidayIndex", "Integer");
      responseValues.put(HolidayIndexResponseValue, HolidayIndex);
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo LocalStartTimeResponseValue =
          new CommandResponseInfo("LocalStartTime", "Optional<Long>");
      responseValues.put(LocalStartTimeResponseValue, LocalStartTime);
      CommandResponseInfo LocalEndTimeResponseValue =
          new CommandResponseInfo("LocalEndTime", "Optional<Long>");
      responseValues.put(LocalEndTimeResponseValue, LocalEndTime);
      CommandResponseInfo OperatingModeResponseValue =
          new CommandResponseInfo("OperatingMode", "Optional<Integer>");
      responseValues.put(OperatingModeResponseValue, OperatingMode);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedDoorLockClusterGetUserResponseCallback
      implements ChipClusters.DoorLockCluster.GetUserResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer UserIndex,
        @Nullable String UserName,
        @Nullable Long UserUniqueID,
        @Nullable Integer UserStatus,
        @Nullable Integer UserType,
        @Nullable Integer CredentialRule,
        @Nullable ArrayList<ChipStructs.DoorLockClusterCredentialStruct> Credentials,
        @Nullable Integer CreatorFabricIndex,
        @Nullable Integer LastModifiedFabricIndex,
        @Nullable Integer NextUserIndex) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo UserIndexResponseValue = new CommandResponseInfo("UserIndex", "Integer");
      responseValues.put(UserIndexResponseValue, UserIndex);
      CommandResponseInfo UserNameResponseValue = new CommandResponseInfo("UserName", "String");
      responseValues.put(UserNameResponseValue, UserName);
      CommandResponseInfo UserUniqueIDResponseValue =
          new CommandResponseInfo("UserUniqueID", "Long");
      responseValues.put(UserUniqueIDResponseValue, UserUniqueID);
      CommandResponseInfo UserStatusResponseValue =
          new CommandResponseInfo("UserStatus", "Integer");
      responseValues.put(UserStatusResponseValue, UserStatus);
      CommandResponseInfo UserTypeResponseValue = new CommandResponseInfo("UserType", "Integer");
      responseValues.put(UserTypeResponseValue, UserType);
      CommandResponseInfo CredentialRuleResponseValue =
          new CommandResponseInfo("CredentialRule", "Integer");
      responseValues.put(CredentialRuleResponseValue, CredentialRule);
      // Credentials: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      CommandResponseInfo CreatorFabricIndexResponseValue =
          new CommandResponseInfo("CreatorFabricIndex", "Integer");
      responseValues.put(CreatorFabricIndexResponseValue, CreatorFabricIndex);
      CommandResponseInfo LastModifiedFabricIndexResponseValue =
          new CommandResponseInfo("LastModifiedFabricIndex", "Integer");
      responseValues.put(LastModifiedFabricIndexResponseValue, LastModifiedFabricIndex);
      CommandResponseInfo NextUserIndexResponseValue =
          new CommandResponseInfo("NextUserIndex", "Integer");
      responseValues.put(NextUserIndexResponseValue, NextUserIndex);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedDoorLockClusterSetCredentialResponseCallback
      implements ChipClusters.DoorLockCluster.SetCredentialResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer Status, @Nullable Integer UserIndex, @Nullable Integer NextCredentialIndex) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo UserIndexResponseValue = new CommandResponseInfo("UserIndex", "Integer");
      responseValues.put(UserIndexResponseValue, UserIndex);
      CommandResponseInfo NextCredentialIndexResponseValue =
          new CommandResponseInfo("NextCredentialIndex", "Integer");
      responseValues.put(NextCredentialIndexResponseValue, NextCredentialIndex);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedDoorLockClusterGetCredentialStatusResponseCallback
      implements ChipClusters.DoorLockCluster.GetCredentialStatusResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Boolean CredentialExists,
        @Nullable Integer UserIndex,
        @Nullable Integer CreatorFabricIndex,
        @Nullable Integer LastModifiedFabricIndex,
        @Nullable Integer NextCredentialIndex) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo CredentialExistsResponseValue =
          new CommandResponseInfo("CredentialExists", "Boolean");
      responseValues.put(CredentialExistsResponseValue, CredentialExists);
      CommandResponseInfo UserIndexResponseValue = new CommandResponseInfo("UserIndex", "Integer");
      responseValues.put(UserIndexResponseValue, UserIndex);
      CommandResponseInfo CreatorFabricIndexResponseValue =
          new CommandResponseInfo("CreatorFabricIndex", "Integer");
      responseValues.put(CreatorFabricIndexResponseValue, CreatorFabricIndex);
      CommandResponseInfo LastModifiedFabricIndexResponseValue =
          new CommandResponseInfo("LastModifiedFabricIndex", "Integer");
      responseValues.put(LastModifiedFabricIndexResponseValue, LastModifiedFabricIndex);
      CommandResponseInfo NextCredentialIndexResponseValue =
          new CommandResponseInfo("NextCredentialIndex", "Integer");
      responseValues.put(NextCredentialIndexResponseValue, NextCredentialIndex);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedDoorLockClusterLockStateAttributeCallback
      implements ChipClusters.DoorLockCluster.LockStateAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDoorLockClusterDoorStateAttributeCallback
      implements ChipClusters.DoorLockCluster.DoorStateAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDoorLockClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.DoorLockCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDoorLockClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.DoorLockCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDoorLockClusterEventListAttributeCallback
      implements ChipClusters.DoorLockCluster.EventListAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedDoorLockClusterAttributeListAttributeCallback
      implements ChipClusters.DoorLockCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWindowCoveringClusterCurrentPositionLiftAttributeCallback
      implements ChipClusters.WindowCoveringCluster.CurrentPositionLiftAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWindowCoveringClusterCurrentPositionTiltAttributeCallback
      implements ChipClusters.WindowCoveringCluster.CurrentPositionTiltAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWindowCoveringClusterCurrentPositionLiftPercentageAttributeCallback
      implements ChipClusters.WindowCoveringCluster.CurrentPositionLiftPercentageAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWindowCoveringClusterCurrentPositionTiltPercentageAttributeCallback
      implements ChipClusters.WindowCoveringCluster.CurrentPositionTiltPercentageAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWindowCoveringClusterTargetPositionLiftPercent100thsAttributeCallback
      implements ChipClusters.WindowCoveringCluster
              .TargetPositionLiftPercent100thsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWindowCoveringClusterTargetPositionTiltPercent100thsAttributeCallback
      implements ChipClusters.WindowCoveringCluster
              .TargetPositionTiltPercent100thsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedWindowCoveringClusterCurrentPositionLiftPercent100thsAttributeCallback
      implements ChipClusters.WindowCoveringCluster
              .CurrentPositionLiftPercent100thsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedWindowCoveringClusterCurrentPositionTiltPercent100thsAttributeCallback
      implements ChipClusters.WindowCoveringCluster
              .CurrentPositionTiltPercent100thsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWindowCoveringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.WindowCoveringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWindowCoveringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.WindowCoveringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWindowCoveringClusterEventListAttributeCallback
      implements ChipClusters.WindowCoveringCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWindowCoveringClusterAttributeListAttributeCallback
      implements ChipClusters.WindowCoveringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBarrierControlClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BarrierControlCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBarrierControlClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BarrierControlCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBarrierControlClusterEventListAttributeCallback
      implements ChipClusters.BarrierControlCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBarrierControlClusterAttributeListAttributeCallback
      implements ChipClusters.BarrierControlCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMaxPressureAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MaxPressureAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMaxSpeedAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MaxSpeedAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMaxFlowAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MaxFlowAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMinConstPressureAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MinConstPressureAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMaxConstPressureAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MaxConstPressureAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMinCompPressureAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MinCompPressureAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMaxCompPressureAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MaxCompPressureAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMinConstSpeedAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MinConstSpeedAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMaxConstSpeedAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MaxConstSpeedAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMinConstFlowAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MinConstFlowAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMaxConstFlowAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MaxConstFlowAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMinConstTempAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MinConstTempAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterMaxConstTempAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.MaxConstTempAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterCapacityAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.CapacityAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterSpeedAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.SpeedAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedPumpConfigurationAndControlClusterLifetimeRunningHoursAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster
              .LifetimeRunningHoursAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterPowerAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.PowerAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedPumpConfigurationAndControlClusterLifetimeEnergyConsumedAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster
              .LifetimeEnergyConsumedAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedPumpConfigurationAndControlClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedPumpConfigurationAndControlClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterEventListAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPumpConfigurationAndControlClusterAttributeListAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterGetWeeklyScheduleResponseCallback
      implements ChipClusters.ThermostatCluster.GetWeeklyScheduleResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Integer NumberOfTransitionsForSequence,
        Integer DayOfWeekForSequence,
        Integer ModeForSequence,
        ArrayList<ChipStructs.ThermostatClusterThermostatScheduleTransition> Transitions) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo NumberOfTransitionsForSequenceResponseValue =
          new CommandResponseInfo("NumberOfTransitionsForSequence", "Integer");
      responseValues.put(
          NumberOfTransitionsForSequenceResponseValue, NumberOfTransitionsForSequence);
      CommandResponseInfo DayOfWeekForSequenceResponseValue =
          new CommandResponseInfo("DayOfWeekForSequence", "Integer");
      responseValues.put(DayOfWeekForSequenceResponseValue, DayOfWeekForSequence);
      CommandResponseInfo ModeForSequenceResponseValue =
          new CommandResponseInfo("ModeForSequence", "Integer");
      responseValues.put(ModeForSequenceResponseValue, ModeForSequence);
      // Transitions: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedThermostatClusterLocalTemperatureAttributeCallback
      implements ChipClusters.ThermostatCluster.LocalTemperatureAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterOutdoorTemperatureAttributeCallback
      implements ChipClusters.ThermostatCluster.OutdoorTemperatureAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterTemperatureSetpointHoldDurationAttributeCallback
      implements ChipClusters.ThermostatCluster.TemperatureSetpointHoldDurationAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterSetpointChangeAmountAttributeCallback
      implements ChipClusters.ThermostatCluster.SetpointChangeAmountAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterOccupiedSetbackAttributeCallback
      implements ChipClusters.ThermostatCluster.OccupiedSetbackAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterOccupiedSetbackMinAttributeCallback
      implements ChipClusters.ThermostatCluster.OccupiedSetbackMinAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterOccupiedSetbackMaxAttributeCallback
      implements ChipClusters.ThermostatCluster.OccupiedSetbackMaxAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterUnoccupiedSetbackAttributeCallback
      implements ChipClusters.ThermostatCluster.UnoccupiedSetbackAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterUnoccupiedSetbackMinAttributeCallback
      implements ChipClusters.ThermostatCluster.UnoccupiedSetbackMinAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterUnoccupiedSetbackMaxAttributeCallback
      implements ChipClusters.ThermostatCluster.UnoccupiedSetbackMaxAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterACCoilTemperatureAttributeCallback
      implements ChipClusters.ThermostatCluster.ACCoilTemperatureAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ThermostatCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ThermostatCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterEventListAttributeCallback
      implements ChipClusters.ThermostatCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatClusterAttributeListAttributeCallback
      implements ChipClusters.ThermostatCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFanControlClusterPercentSettingAttributeCallback
      implements ChipClusters.FanControlCluster.PercentSettingAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFanControlClusterSpeedSettingAttributeCallback
      implements ChipClusters.FanControlCluster.SpeedSettingAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFanControlClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.FanControlCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFanControlClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.FanControlCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFanControlClusterEventListAttributeCallback
      implements ChipClusters.FanControlCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFanControlClusterAttributeListAttributeCallback
      implements ChipClusters.FanControlCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedThermostatUserInterfaceConfigurationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ThermostatUserInterfaceConfigurationCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedThermostatUserInterfaceConfigurationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ThermostatUserInterfaceConfigurationCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedThermostatUserInterfaceConfigurationClusterEventListAttributeCallback
      implements ChipClusters.ThermostatUserInterfaceConfigurationCluster
              .EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedThermostatUserInterfaceConfigurationClusterAttributeListAttributeCallback
      implements ChipClusters.ThermostatUserInterfaceConfigurationCluster
              .AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterNumberOfPrimariesAttributeCallback
      implements ChipClusters.ColorControlCluster.NumberOfPrimariesAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterPrimary1IntensityAttributeCallback
      implements ChipClusters.ColorControlCluster.Primary1IntensityAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterPrimary2IntensityAttributeCallback
      implements ChipClusters.ColorControlCluster.Primary2IntensityAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterPrimary3IntensityAttributeCallback
      implements ChipClusters.ColorControlCluster.Primary3IntensityAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterPrimary4IntensityAttributeCallback
      implements ChipClusters.ColorControlCluster.Primary4IntensityAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterPrimary5IntensityAttributeCallback
      implements ChipClusters.ColorControlCluster.Primary5IntensityAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterPrimary6IntensityAttributeCallback
      implements ChipClusters.ColorControlCluster.Primary6IntensityAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterColorPointRIntensityAttributeCallback
      implements ChipClusters.ColorControlCluster.ColorPointRIntensityAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterColorPointGIntensityAttributeCallback
      implements ChipClusters.ColorControlCluster.ColorPointGIntensityAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterColorPointBIntensityAttributeCallback
      implements ChipClusters.ColorControlCluster.ColorPointBIntensityAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterStartUpColorTemperatureMiredsAttributeCallback
      implements ChipClusters.ColorControlCluster.StartUpColorTemperatureMiredsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ColorControlCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ColorControlCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterEventListAttributeCallback
      implements ChipClusters.ColorControlCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedColorControlClusterAttributeListAttributeCallback
      implements ChipClusters.ColorControlCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBallastConfigurationClusterIntrinsicBallastFactorAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.IntrinsicBallastFactorAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBallastConfigurationClusterBallastFactorAdjustmentAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.BallastFactorAdjustmentAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBallastConfigurationClusterLampRatedHoursAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.LampRatedHoursAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBallastConfigurationClusterLampBurnHoursAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.LampBurnHoursAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBallastConfigurationClusterLampBurnHoursTripPointAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.LampBurnHoursTripPointAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBallastConfigurationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBallastConfigurationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBallastConfigurationClusterEventListAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedBallastConfigurationClusterAttributeListAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIlluminanceMeasurementClusterMeasuredValueAttributeCallback
      implements ChipClusters.IlluminanceMeasurementCluster.MeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIlluminanceMeasurementClusterMinMeasuredValueAttributeCallback
      implements ChipClusters.IlluminanceMeasurementCluster.MinMeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIlluminanceMeasurementClusterMaxMeasuredValueAttributeCallback
      implements ChipClusters.IlluminanceMeasurementCluster.MaxMeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIlluminanceMeasurementClusterLightSensorTypeAttributeCallback
      implements ChipClusters.IlluminanceMeasurementCluster.LightSensorTypeAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIlluminanceMeasurementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.IlluminanceMeasurementCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIlluminanceMeasurementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.IlluminanceMeasurementCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIlluminanceMeasurementClusterEventListAttributeCallback
      implements ChipClusters.IlluminanceMeasurementCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedIlluminanceMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.IlluminanceMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureMeasurementClusterMeasuredValueAttributeCallback
      implements ChipClusters.TemperatureMeasurementCluster.MeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureMeasurementClusterMinMeasuredValueAttributeCallback
      implements ChipClusters.TemperatureMeasurementCluster.MinMeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureMeasurementClusterMaxMeasuredValueAttributeCallback
      implements ChipClusters.TemperatureMeasurementCluster.MaxMeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureMeasurementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.TemperatureMeasurementCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureMeasurementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.TemperatureMeasurementCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureMeasurementClusterEventListAttributeCallback
      implements ChipClusters.TemperatureMeasurementCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTemperatureMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.TemperatureMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPressureMeasurementClusterMeasuredValueAttributeCallback
      implements ChipClusters.PressureMeasurementCluster.MeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPressureMeasurementClusterMinMeasuredValueAttributeCallback
      implements ChipClusters.PressureMeasurementCluster.MinMeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPressureMeasurementClusterMaxMeasuredValueAttributeCallback
      implements ChipClusters.PressureMeasurementCluster.MaxMeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPressureMeasurementClusterScaledValueAttributeCallback
      implements ChipClusters.PressureMeasurementCluster.ScaledValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPressureMeasurementClusterMinScaledValueAttributeCallback
      implements ChipClusters.PressureMeasurementCluster.MinScaledValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPressureMeasurementClusterMaxScaledValueAttributeCallback
      implements ChipClusters.PressureMeasurementCluster.MaxScaledValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPressureMeasurementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.PressureMeasurementCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPressureMeasurementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.PressureMeasurementCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPressureMeasurementClusterEventListAttributeCallback
      implements ChipClusters.PressureMeasurementCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedPressureMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.PressureMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFlowMeasurementClusterMeasuredValueAttributeCallback
      implements ChipClusters.FlowMeasurementCluster.MeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFlowMeasurementClusterMinMeasuredValueAttributeCallback
      implements ChipClusters.FlowMeasurementCluster.MinMeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFlowMeasurementClusterMaxMeasuredValueAttributeCallback
      implements ChipClusters.FlowMeasurementCluster.MaxMeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFlowMeasurementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.FlowMeasurementCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFlowMeasurementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.FlowMeasurementCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFlowMeasurementClusterEventListAttributeCallback
      implements ChipClusters.FlowMeasurementCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFlowMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.FlowMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedRelativeHumidityMeasurementClusterMeasuredValueAttributeCallback
      implements ChipClusters.RelativeHumidityMeasurementCluster.MeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedRelativeHumidityMeasurementClusterMinMeasuredValueAttributeCallback
      implements ChipClusters.RelativeHumidityMeasurementCluster.MinMeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedRelativeHumidityMeasurementClusterMaxMeasuredValueAttributeCallback
      implements ChipClusters.RelativeHumidityMeasurementCluster.MaxMeasuredValueAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedRelativeHumidityMeasurementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.RelativeHumidityMeasurementCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static
  class DelegatedRelativeHumidityMeasurementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.RelativeHumidityMeasurementCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedRelativeHumidityMeasurementClusterEventListAttributeCallback
      implements ChipClusters.RelativeHumidityMeasurementCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedRelativeHumidityMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.RelativeHumidityMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOccupancySensingClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.OccupancySensingCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOccupancySensingClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.OccupancySensingCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOccupancySensingClusterEventListAttributeCallback
      implements ChipClusters.OccupancySensingCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedOccupancySensingClusterAttributeListAttributeCallback
      implements ChipClusters.OccupancySensingCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWakeOnLanClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.WakeOnLanCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWakeOnLanClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.WakeOnLanCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWakeOnLanClusterEventListAttributeCallback
      implements ChipClusters.WakeOnLanCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedWakeOnLanClusterAttributeListAttributeCallback
      implements ChipClusters.WakeOnLanCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedChannelClusterChangeChannelResponseCallback
      implements ChipClusters.ChannelCluster.ChangeChannelResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Optional<String> Data) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo DataResponseValue = new CommandResponseInfo("Data", "Optional<String>");
      responseValues.put(DataResponseValue, Data);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedChannelClusterChannelListAttributeCallback
      implements ChipClusters.ChannelCluster.ChannelListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.ChannelClusterChannelInfoStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<ChipStructs.ChannelClusterChannelInfoStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedChannelClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ChannelCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedChannelClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ChannelCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedChannelClusterEventListAttributeCallback
      implements ChipClusters.ChannelCluster.EventListAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedChannelClusterAttributeListAttributeCallback
      implements ChipClusters.ChannelCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTargetNavigatorClusterNavigateTargetResponseCallback
      implements ChipClusters.TargetNavigatorCluster.NavigateTargetResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Optional<String> Data) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo DataResponseValue = new CommandResponseInfo("Data", "Optional<String>");
      responseValues.put(DataResponseValue, Data);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedTargetNavigatorClusterTargetListAttributeCallback
      implements ChipClusters.TargetNavigatorCluster.TargetListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.TargetNavigatorClusterTargetInfoStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.TargetNavigatorClusterTargetInfoStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTargetNavigatorClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.TargetNavigatorCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTargetNavigatorClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.TargetNavigatorCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTargetNavigatorClusterEventListAttributeCallback
      implements ChipClusters.TargetNavigatorCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTargetNavigatorClusterAttributeListAttributeCallback
      implements ChipClusters.TargetNavigatorCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaPlaybackClusterPlaybackResponseCallback
      implements ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Optional<String> Data) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo DataResponseValue = new CommandResponseInfo("Data", "Optional<String>");
      responseValues.put(DataResponseValue, Data);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedMediaPlaybackClusterStartTimeAttributeCallback
      implements ChipClusters.MediaPlaybackCluster.StartTimeAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaPlaybackClusterDurationAttributeCallback
      implements ChipClusters.MediaPlaybackCluster.DurationAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaPlaybackClusterSeekRangeEndAttributeCallback
      implements ChipClusters.MediaPlaybackCluster.SeekRangeEndAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaPlaybackClusterSeekRangeStartAttributeCallback
      implements ChipClusters.MediaPlaybackCluster.SeekRangeStartAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaPlaybackClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.MediaPlaybackCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaPlaybackClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.MediaPlaybackCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaPlaybackClusterEventListAttributeCallback
      implements ChipClusters.MediaPlaybackCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaPlaybackClusterAttributeListAttributeCallback
      implements ChipClusters.MediaPlaybackCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaInputClusterInputListAttributeCallback
      implements ChipClusters.MediaInputCluster.InputListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.MediaInputClusterInputInfoStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.MediaInputClusterInputInfoStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaInputClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.MediaInputCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaInputClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.MediaInputCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaInputClusterEventListAttributeCallback
      implements ChipClusters.MediaInputCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedMediaInputClusterAttributeListAttributeCallback
      implements ChipClusters.MediaInputCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLowPowerClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.LowPowerCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLowPowerClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.LowPowerCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLowPowerClusterEventListAttributeCallback
      implements ChipClusters.LowPowerCluster.EventListAttributeCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLowPowerClusterAttributeListAttributeCallback
      implements ChipClusters.LowPowerCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedKeypadInputClusterSendKeyResponseCallback
      implements ChipClusters.KeypadInputCluster.SendKeyResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedKeypadInputClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.KeypadInputCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedKeypadInputClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.KeypadInputCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedKeypadInputClusterEventListAttributeCallback
      implements ChipClusters.KeypadInputCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedKeypadInputClusterAttributeListAttributeCallback
      implements ChipClusters.KeypadInputCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedContentLauncherClusterLauncherResponseCallback
      implements ChipClusters.ContentLauncherCluster.LauncherResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Optional<String> Data) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo DataResponseValue = new CommandResponseInfo("Data", "Optional<String>");
      responseValues.put(DataResponseValue, Data);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedContentLauncherClusterAcceptHeaderAttributeCallback
      implements ChipClusters.ContentLauncherCluster.AcceptHeaderAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<String> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<String>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedContentLauncherClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ContentLauncherCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedContentLauncherClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ContentLauncherCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedContentLauncherClusterEventListAttributeCallback
      implements ChipClusters.ContentLauncherCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedContentLauncherClusterAttributeListAttributeCallback
      implements ChipClusters.ContentLauncherCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAudioOutputClusterOutputListAttributeCallback
      implements ChipClusters.AudioOutputCluster.OutputListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.AudioOutputClusterOutputInfoStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.AudioOutputClusterOutputInfoStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAudioOutputClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.AudioOutputCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAudioOutputClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.AudioOutputCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAudioOutputClusterEventListAttributeCallback
      implements ChipClusters.AudioOutputCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAudioOutputClusterAttributeListAttributeCallback
      implements ChipClusters.AudioOutputCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationLauncherClusterLauncherResponseCallback
      implements ChipClusters.ApplicationLauncherCluster.LauncherResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer Status, Optional<byte[]> Data) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo StatusResponseValue = new CommandResponseInfo("Status", "Integer");
      responseValues.put(StatusResponseValue, Status);
      CommandResponseInfo DataResponseValue = new CommandResponseInfo("Data", "Optional<byte[]>");
      responseValues.put(DataResponseValue, Data);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedApplicationLauncherClusterCatalogListAttributeCallback
      implements ChipClusters.ApplicationLauncherCluster.CatalogListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationLauncherClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ApplicationLauncherCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationLauncherClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ApplicationLauncherCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationLauncherClusterEventListAttributeCallback
      implements ChipClusters.ApplicationLauncherCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationLauncherClusterAttributeListAttributeCallback
      implements ChipClusters.ApplicationLauncherCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationBasicClusterAllowedVendorListAttributeCallback
      implements ChipClusters.ApplicationBasicCluster.AllowedVendorListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationBasicClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ApplicationBasicCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationBasicClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ApplicationBasicCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationBasicClusterEventListAttributeCallback
      implements ChipClusters.ApplicationBasicCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationBasicClusterAttributeListAttributeCallback
      implements ChipClusters.ApplicationBasicCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccountLoginClusterGetSetupPINResponseCallback
      implements ChipClusters.AccountLoginCluster.GetSetupPINResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(String SetupPIN) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo SetupPINResponseValue = new CommandResponseInfo("SetupPIN", "String");
      responseValues.put(SetupPINResponseValue, SetupPIN);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedAccountLoginClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.AccountLoginCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccountLoginClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.AccountLoginCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccountLoginClusterEventListAttributeCallback
      implements ChipClusters.AccountLoginCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccountLoginClusterAttributeListAttributeCallback
      implements ChipClusters.AccountLoginCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedElectricalMeasurementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ElectricalMeasurementCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedElectricalMeasurementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ElectricalMeasurementCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedElectricalMeasurementClusterEventListAttributeCallback
      implements ChipClusters.ElectricalMeasurementCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedElectricalMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.ElectricalMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterTestSpecificResponseCallback
      implements ChipClusters.UnitTestingCluster.TestSpecificResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer returnValue) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo returnValueResponseValue =
          new CommandResponseInfo("returnValue", "Integer");
      responseValues.put(returnValueResponseValue, returnValue);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedUnitTestingClusterTestAddArgumentsResponseCallback
      implements ChipClusters.UnitTestingCluster.TestAddArgumentsResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer returnValue) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo returnValueResponseValue =
          new CommandResponseInfo("returnValue", "Integer");
      responseValues.put(returnValueResponseValue, returnValue);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedUnitTestingClusterTestListInt8UReverseResponseCallback
      implements ChipClusters.UnitTestingCluster.TestListInt8UReverseResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(ArrayList<Integer> arg1) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      // arg1: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedUnitTestingClusterTestEnumsResponseCallback
      implements ChipClusters.UnitTestingCluster.TestEnumsResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer arg1, Integer arg2) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo arg1ResponseValue = new CommandResponseInfo("arg1", "Integer");
      responseValues.put(arg1ResponseValue, arg1);
      CommandResponseInfo arg2ResponseValue = new CommandResponseInfo("arg2", "Integer");
      responseValues.put(arg2ResponseValue, arg2);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedUnitTestingClusterTestNullableOptionalResponseCallback
      implements ChipClusters.UnitTestingCluster.TestNullableOptionalResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Boolean wasPresent,
        Optional<Boolean> wasNull,
        Optional<Integer> value,
        @Nullable Optional<Integer> originalValue) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo wasPresentResponseValue =
          new CommandResponseInfo("wasPresent", "Boolean");
      responseValues.put(wasPresentResponseValue, wasPresent);
      CommandResponseInfo wasNullResponseValue =
          new CommandResponseInfo("wasNull", "Optional<Boolean>");
      responseValues.put(wasNullResponseValue, wasNull);
      CommandResponseInfo valueResponseValue =
          new CommandResponseInfo("value", "Optional<Integer>");
      responseValues.put(valueResponseValue, value);
      CommandResponseInfo originalValueResponseValue =
          new CommandResponseInfo("originalValue", "Optional<Integer>");
      responseValues.put(originalValueResponseValue, originalValue);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedUnitTestingClusterBooleanResponseCallback
      implements ChipClusters.UnitTestingCluster.BooleanResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Boolean value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo valueResponseValue = new CommandResponseInfo("value", "Boolean");
      responseValues.put(valueResponseValue, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedUnitTestingClusterSimpleStructResponseCallback
      implements ChipClusters.UnitTestingCluster.SimpleStructResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(ChipStructs.UnitTestingClusterSimpleStruct arg1) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      // arg1: Struct SimpleStruct
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedUnitTestingClusterTestEmitTestEventResponseCallback
      implements ChipClusters.UnitTestingCluster.TestEmitTestEventResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo valueResponseValue = new CommandResponseInfo("value", "Long");
      responseValues.put(valueResponseValue, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedUnitTestingClusterListInt8uAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListInt8uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterListOctetStringAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListOctetStringAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<byte[]> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<byte[]>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterListStructOctetStringAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListStructOctetStringAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.UnitTestingClusterTestListStructOctet> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.UnitTestingClusterTestListStructOctet>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterListNullablesAndOptionalsStructAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListNullablesAndOptionalsStructAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        List<ChipStructs.UnitTestingClusterNullablesAndOptionalsStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.UnitTestingClusterNullablesAndOptionalsStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterListLongOctetStringAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListLongOctetStringAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<byte[]> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<byte[]>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterListFabricScopedAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListFabricScopedAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.UnitTestingClusterTestFabricScoped> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.UnitTestingClusterTestFabricScoped>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableBooleanAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableBooleanAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Boolean value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Boolean");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableBitmap8AttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableBitmap8AttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableBitmap16AttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableBitmap16AttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableBitmap32AttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableBitmap32AttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableBitmap64AttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableBitmap64AttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt8uAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt8uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt16uAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt16uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt24uAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt24uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt32uAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt32uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt40uAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt40uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt48uAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt48uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt56uAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt56uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt64uAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt64uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt8sAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt8sAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt16sAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt16sAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt24sAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt24sAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt32sAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt32sAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt40sAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt40sAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt48sAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt48sAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt56sAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt56sAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableInt64sAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableInt64sAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableEnum8AttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableEnum8AttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableEnum16AttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableEnum16AttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableFloatSingleAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableFloatSingleAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Float value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Float");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableFloatDoubleAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableFloatDoubleAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Double value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Double");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableOctetStringAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableOctetStringAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable byte[] value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "byte[]");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableCharStringAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableCharStringAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable String value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "String");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableEnumAttrAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableEnumAttrAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableRangeRestrictedInt8uAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableRangeRestrictedInt8uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableRangeRestrictedInt8sAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableRangeRestrictedInt8sAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableRangeRestrictedInt16uAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableRangeRestrictedInt16uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterNullableRangeRestrictedInt16sAttributeCallback
      implements ChipClusters.UnitTestingCluster.NullableRangeRestrictedInt16sAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(@Nullable Integer value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
      responseValues.put(commandResponseInfo, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.UnitTestingCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.UnitTestingCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterEventListAttributeCallback
      implements ChipClusters.UnitTestingCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterAttributeListAttributeCallback
      implements ChipClusters.UnitTestingCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFaultInjectionClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.FaultInjectionCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFaultInjectionClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.FaultInjectionCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFaultInjectionClusterEventListAttributeCallback
      implements ChipClusters.FaultInjectionCluster.EventListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedFaultInjectionClusterAttributeListAttributeCallback
      implements ChipClusters.FaultInjectionCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public Map<String, ClusterInfo> getClusterMap() {
    Map<String, ClusterInfo> clusterMap = initializeClusterMap();
    Map<String, Map<String, InteractionInfo>> commandMap = getCommandMap();
    combineCommand(clusterMap, commandMap);
    Map<String, Map<String, InteractionInfo>> readAttributeMap =
        new ClusterReadMapping().getReadAttributeMap();
    combineCommand(clusterMap, readAttributeMap);
    Map<String, Map<String, InteractionInfo>> writeAttributeMap =
        new ClusterWriteMapping().getWriteAttributeMap();
    combineCommand(clusterMap, writeAttributeMap);
    return clusterMap;
  }

  public Map<String, ClusterInfo> initializeClusterMap() {
    Map<String, ClusterInfo> clusterMap = new HashMap<>();
    ClusterInfo identifyClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.IdentifyCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("identify", identifyClusterInfo);
    ClusterInfo groupsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.GroupsCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("groups", groupsClusterInfo);
    ClusterInfo scenesClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ScenesCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("scenes", scenesClusterInfo);
    ClusterInfo onOffClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.OnOffCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("onOff", onOffClusterInfo);
    ClusterInfo onOffSwitchConfigurationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.OnOffSwitchConfigurationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("onOffSwitchConfiguration", onOffSwitchConfigurationClusterInfo);
    ClusterInfo levelControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.LevelControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("levelControl", levelControlClusterInfo);
    ClusterInfo binaryInputBasicClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BinaryInputBasicCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("binaryInputBasic", binaryInputBasicClusterInfo);
    ClusterInfo pulseWidthModulationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.PulseWidthModulationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("pulseWidthModulation", pulseWidthModulationClusterInfo);
    ClusterInfo descriptorClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.DescriptorCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("descriptor", descriptorClusterInfo);
    ClusterInfo bindingClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BindingCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("binding", bindingClusterInfo);
    ClusterInfo accessControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.AccessControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("accessControl", accessControlClusterInfo);
    ClusterInfo actionsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ActionsCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("actions", actionsClusterInfo);
    ClusterInfo basicInformationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BasicInformationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("basicInformation", basicInformationClusterInfo);
    ClusterInfo otaSoftwareUpdateProviderClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.OtaSoftwareUpdateProviderCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("otaSoftwareUpdateProvider", otaSoftwareUpdateProviderClusterInfo);
    ClusterInfo otaSoftwareUpdateRequestorClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.OtaSoftwareUpdateRequestorCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("otaSoftwareUpdateRequestor", otaSoftwareUpdateRequestorClusterInfo);
    ClusterInfo localizationConfigurationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.LocalizationConfigurationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("localizationConfiguration", localizationConfigurationClusterInfo);
    ClusterInfo timeFormatLocalizationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.TimeFormatLocalizationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("timeFormatLocalization", timeFormatLocalizationClusterInfo);
    ClusterInfo unitLocalizationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.UnitLocalizationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("unitLocalization", unitLocalizationClusterInfo);
    ClusterInfo powerSourceConfigurationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.PowerSourceConfigurationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("powerSourceConfiguration", powerSourceConfigurationClusterInfo);
    ClusterInfo powerSourceClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.PowerSourceCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("powerSource", powerSourceClusterInfo);
    ClusterInfo generalCommissioningClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.GeneralCommissioningCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("generalCommissioning", generalCommissioningClusterInfo);
    ClusterInfo networkCommissioningClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.NetworkCommissioningCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("networkCommissioning", networkCommissioningClusterInfo);
    ClusterInfo diagnosticLogsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.DiagnosticLogsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("diagnosticLogs", diagnosticLogsClusterInfo);
    ClusterInfo generalDiagnosticsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.GeneralDiagnosticsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("generalDiagnostics", generalDiagnosticsClusterInfo);
    ClusterInfo softwareDiagnosticsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.SoftwareDiagnosticsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("softwareDiagnostics", softwareDiagnosticsClusterInfo);
    ClusterInfo threadNetworkDiagnosticsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ThreadNetworkDiagnosticsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("threadNetworkDiagnostics", threadNetworkDiagnosticsClusterInfo);
    ClusterInfo wiFiNetworkDiagnosticsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.WiFiNetworkDiagnosticsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("wiFiNetworkDiagnostics", wiFiNetworkDiagnosticsClusterInfo);
    ClusterInfo ethernetNetworkDiagnosticsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.EthernetNetworkDiagnosticsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("ethernetNetworkDiagnostics", ethernetNetworkDiagnosticsClusterInfo);
    ClusterInfo timeSynchronizationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.TimeSynchronizationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("timeSynchronization", timeSynchronizationClusterInfo);
    ClusterInfo bridgedDeviceBasicInformationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.BridgedDeviceBasicInformationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("bridgedDeviceBasicInformation", bridgedDeviceBasicInformationClusterInfo);
    ClusterInfo switchClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.SwitchCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("switch", switchClusterInfo);
    ClusterInfo administratorCommissioningClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.AdministratorCommissioningCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("administratorCommissioning", administratorCommissioningClusterInfo);
    ClusterInfo operationalCredentialsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.OperationalCredentialsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("operationalCredentials", operationalCredentialsClusterInfo);
    ClusterInfo groupKeyManagementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.GroupKeyManagementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("groupKeyManagement", groupKeyManagementClusterInfo);
    ClusterInfo fixedLabelClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.FixedLabelCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("fixedLabel", fixedLabelClusterInfo);
    ClusterInfo userLabelClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.UserLabelCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("userLabel", userLabelClusterInfo);
    ClusterInfo proxyConfigurationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ProxyConfigurationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("proxyConfiguration", proxyConfigurationClusterInfo);
    ClusterInfo proxyDiscoveryClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ProxyDiscoveryCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("proxyDiscovery", proxyDiscoveryClusterInfo);
    ClusterInfo proxyValidClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ProxyValidCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("proxyValid", proxyValidClusterInfo);
    ClusterInfo booleanStateClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BooleanStateCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("booleanState", booleanStateClusterInfo);
    ClusterInfo icdManagementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.IcdManagementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("icdManagement", icdManagementClusterInfo);
    ClusterInfo modeSelectClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ModeSelectCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("modeSelect", modeSelectClusterInfo);
    ClusterInfo temperatureControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.TemperatureControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("temperatureControl", temperatureControlClusterInfo);
    ClusterInfo refrigeratorAlarmClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.RefrigeratorAlarmCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("refrigeratorAlarm", refrigeratorAlarmClusterInfo);
    ClusterInfo airQualityClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.AirQualityCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("airQuality", airQualityClusterInfo);
    ClusterInfo smokeCoAlarmClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.SmokeCoAlarmCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("smokeCoAlarm", smokeCoAlarmClusterInfo);
    ClusterInfo hepaFilterMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.HepaFilterMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("hepaFilterMonitoring", hepaFilterMonitoringClusterInfo);
    ClusterInfo activatedCarbonFilterMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.ActivatedCarbonFilterMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("activatedCarbonFilterMonitoring", activatedCarbonFilterMonitoringClusterInfo);
    ClusterInfo ceramicFilterMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.CeramicFilterMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("ceramicFilterMonitoring", ceramicFilterMonitoringClusterInfo);
    ClusterInfo electrostaticFilterMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.ElectrostaticFilterMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("electrostaticFilterMonitoring", electrostaticFilterMonitoringClusterInfo);
    ClusterInfo uvFilterMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.UvFilterMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("uvFilterMonitoring", uvFilterMonitoringClusterInfo);
    ClusterInfo ionizingFilterMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.IonizingFilterMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("ionizingFilterMonitoring", ionizingFilterMonitoringClusterInfo);
    ClusterInfo zeoliteFilterMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ZeoliteFilterMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("zeoliteFilterMonitoring", zeoliteFilterMonitoringClusterInfo);
    ClusterInfo ozoneFilterMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.OzoneFilterMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("ozoneFilterMonitoring", ozoneFilterMonitoringClusterInfo);
    ClusterInfo waterTankMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.WaterTankMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("waterTankMonitoring", waterTankMonitoringClusterInfo);
    ClusterInfo fuelTankMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.FuelTankMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("fuelTankMonitoring", fuelTankMonitoringClusterInfo);
    ClusterInfo inkCartridgeMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.InkCartridgeMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("inkCartridgeMonitoring", inkCartridgeMonitoringClusterInfo);
    ClusterInfo tonerCartridgeMonitoringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.TonerCartridgeMonitoringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("tonerCartridgeMonitoring", tonerCartridgeMonitoringClusterInfo);
    ClusterInfo doorLockClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.DoorLockCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("doorLock", doorLockClusterInfo);
    ClusterInfo windowCoveringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.WindowCoveringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("windowCovering", windowCoveringClusterInfo);
    ClusterInfo barrierControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BarrierControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("barrierControl", barrierControlClusterInfo);
    ClusterInfo pumpConfigurationAndControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.PumpConfigurationAndControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("pumpConfigurationAndControl", pumpConfigurationAndControlClusterInfo);
    ClusterInfo thermostatClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ThermostatCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("thermostat", thermostatClusterInfo);
    ClusterInfo fanControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.FanControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("fanControl", fanControlClusterInfo);
    ClusterInfo thermostatUserInterfaceConfigurationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.ThermostatUserInterfaceConfigurationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put(
        "thermostatUserInterfaceConfiguration", thermostatUserInterfaceConfigurationClusterInfo);
    ClusterInfo colorControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ColorControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("colorControl", colorControlClusterInfo);
    ClusterInfo ballastConfigurationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BallastConfigurationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("ballastConfiguration", ballastConfigurationClusterInfo);
    ClusterInfo illuminanceMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.IlluminanceMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("illuminanceMeasurement", illuminanceMeasurementClusterInfo);
    ClusterInfo temperatureMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.TemperatureMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("temperatureMeasurement", temperatureMeasurementClusterInfo);
    ClusterInfo pressureMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.PressureMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("pressureMeasurement", pressureMeasurementClusterInfo);
    ClusterInfo flowMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.FlowMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("flowMeasurement", flowMeasurementClusterInfo);
    ClusterInfo relativeHumidityMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.RelativeHumidityMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("relativeHumidityMeasurement", relativeHumidityMeasurementClusterInfo);
    ClusterInfo occupancySensingClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.OccupancySensingCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("occupancySensing", occupancySensingClusterInfo);
    ClusterInfo wakeOnLanClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.WakeOnLanCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("wakeOnLan", wakeOnLanClusterInfo);
    ClusterInfo channelClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ChannelCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("channel", channelClusterInfo);
    ClusterInfo targetNavigatorClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.TargetNavigatorCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("targetNavigator", targetNavigatorClusterInfo);
    ClusterInfo mediaPlaybackClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.MediaPlaybackCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("mediaPlayback", mediaPlaybackClusterInfo);
    ClusterInfo mediaInputClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.MediaInputCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("mediaInput", mediaInputClusterInfo);
    ClusterInfo lowPowerClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.LowPowerCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("lowPower", lowPowerClusterInfo);
    ClusterInfo keypadInputClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.KeypadInputCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("keypadInput", keypadInputClusterInfo);
    ClusterInfo contentLauncherClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ContentLauncherCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("contentLauncher", contentLauncherClusterInfo);
    ClusterInfo audioOutputClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.AudioOutputCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("audioOutput", audioOutputClusterInfo);
    ClusterInfo applicationLauncherClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ApplicationLauncherCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("applicationLauncher", applicationLauncherClusterInfo);
    ClusterInfo applicationBasicClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ApplicationBasicCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("applicationBasic", applicationBasicClusterInfo);
    ClusterInfo accountLoginClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.AccountLoginCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("accountLogin", accountLoginClusterInfo);
    ClusterInfo electricalMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ElectricalMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("electricalMeasurement", electricalMeasurementClusterInfo);
    ClusterInfo unitTestingClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.UnitTestingCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("unitTesting", unitTestingClusterInfo);
    ClusterInfo faultInjectionClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.FaultInjectionCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("faultInjection", faultInjectionClusterInfo);
    return clusterMap;
  }

  public void combineCommand(
      Map<String, ClusterInfo> destination, Map<String, Map<String, InteractionInfo>> source) {
    destination.get("identify").combineCommands(source.get("identify"));
    destination.get("groups").combineCommands(source.get("groups"));
    destination.get("scenes").combineCommands(source.get("scenes"));
    destination.get("onOff").combineCommands(source.get("onOff"));
    destination
        .get("onOffSwitchConfiguration")
        .combineCommands(source.get("onOffSwitchConfiguration"));
    destination.get("levelControl").combineCommands(source.get("levelControl"));
    destination.get("binaryInputBasic").combineCommands(source.get("binaryInputBasic"));
    destination.get("pulseWidthModulation").combineCommands(source.get("pulseWidthModulation"));
    destination.get("descriptor").combineCommands(source.get("descriptor"));
    destination.get("binding").combineCommands(source.get("binding"));
    destination.get("accessControl").combineCommands(source.get("accessControl"));
    destination.get("actions").combineCommands(source.get("actions"));
    destination.get("basicInformation").combineCommands(source.get("basicInformation"));
    destination
        .get("otaSoftwareUpdateProvider")
        .combineCommands(source.get("otaSoftwareUpdateProvider"));
    destination
        .get("otaSoftwareUpdateRequestor")
        .combineCommands(source.get("otaSoftwareUpdateRequestor"));
    destination
        .get("localizationConfiguration")
        .combineCommands(source.get("localizationConfiguration"));
    destination.get("timeFormatLocalization").combineCommands(source.get("timeFormatLocalization"));
    destination.get("unitLocalization").combineCommands(source.get("unitLocalization"));
    destination
        .get("powerSourceConfiguration")
        .combineCommands(source.get("powerSourceConfiguration"));
    destination.get("powerSource").combineCommands(source.get("powerSource"));
    destination.get("generalCommissioning").combineCommands(source.get("generalCommissioning"));
    destination.get("networkCommissioning").combineCommands(source.get("networkCommissioning"));
    destination.get("diagnosticLogs").combineCommands(source.get("diagnosticLogs"));
    destination.get("generalDiagnostics").combineCommands(source.get("generalDiagnostics"));
    destination.get("softwareDiagnostics").combineCommands(source.get("softwareDiagnostics"));
    destination
        .get("threadNetworkDiagnostics")
        .combineCommands(source.get("threadNetworkDiagnostics"));
    destination.get("wiFiNetworkDiagnostics").combineCommands(source.get("wiFiNetworkDiagnostics"));
    destination
        .get("ethernetNetworkDiagnostics")
        .combineCommands(source.get("ethernetNetworkDiagnostics"));
    destination.get("timeSynchronization").combineCommands(source.get("timeSynchronization"));
    destination
        .get("bridgedDeviceBasicInformation")
        .combineCommands(source.get("bridgedDeviceBasicInformation"));
    destination.get("switch").combineCommands(source.get("switch"));
    destination
        .get("administratorCommissioning")
        .combineCommands(source.get("administratorCommissioning"));
    destination.get("operationalCredentials").combineCommands(source.get("operationalCredentials"));
    destination.get("groupKeyManagement").combineCommands(source.get("groupKeyManagement"));
    destination.get("fixedLabel").combineCommands(source.get("fixedLabel"));
    destination.get("userLabel").combineCommands(source.get("userLabel"));
    destination.get("proxyConfiguration").combineCommands(source.get("proxyConfiguration"));
    destination.get("proxyDiscovery").combineCommands(source.get("proxyDiscovery"));
    destination.get("proxyValid").combineCommands(source.get("proxyValid"));
    destination.get("booleanState").combineCommands(source.get("booleanState"));
    destination.get("icdManagement").combineCommands(source.get("icdManagement"));
    destination.get("modeSelect").combineCommands(source.get("modeSelect"));
    destination.get("temperatureControl").combineCommands(source.get("temperatureControl"));
    destination.get("refrigeratorAlarm").combineCommands(source.get("refrigeratorAlarm"));
    destination.get("airQuality").combineCommands(source.get("airQuality"));
    destination.get("smokeCoAlarm").combineCommands(source.get("smokeCoAlarm"));
    destination.get("hepaFilterMonitoring").combineCommands(source.get("hepaFilterMonitoring"));
    destination
        .get("activatedCarbonFilterMonitoring")
        .combineCommands(source.get("activatedCarbonFilterMonitoring"));
    destination
        .get("ceramicFilterMonitoring")
        .combineCommands(source.get("ceramicFilterMonitoring"));
    destination
        .get("electrostaticFilterMonitoring")
        .combineCommands(source.get("electrostaticFilterMonitoring"));
    destination.get("uvFilterMonitoring").combineCommands(source.get("uvFilterMonitoring"));
    destination
        .get("ionizingFilterMonitoring")
        .combineCommands(source.get("ionizingFilterMonitoring"));
    destination
        .get("zeoliteFilterMonitoring")
        .combineCommands(source.get("zeoliteFilterMonitoring"));
    destination.get("ozoneFilterMonitoring").combineCommands(source.get("ozoneFilterMonitoring"));
    destination.get("waterTankMonitoring").combineCommands(source.get("waterTankMonitoring"));
    destination.get("fuelTankMonitoring").combineCommands(source.get("fuelTankMonitoring"));
    destination.get("inkCartridgeMonitoring").combineCommands(source.get("inkCartridgeMonitoring"));
    destination
        .get("tonerCartridgeMonitoring")
        .combineCommands(source.get("tonerCartridgeMonitoring"));
    destination.get("doorLock").combineCommands(source.get("doorLock"));
    destination.get("windowCovering").combineCommands(source.get("windowCovering"));
    destination.get("barrierControl").combineCommands(source.get("barrierControl"));
    destination
        .get("pumpConfigurationAndControl")
        .combineCommands(source.get("pumpConfigurationAndControl"));
    destination.get("thermostat").combineCommands(source.get("thermostat"));
    destination.get("fanControl").combineCommands(source.get("fanControl"));
    destination
        .get("thermostatUserInterfaceConfiguration")
        .combineCommands(source.get("thermostatUserInterfaceConfiguration"));
    destination.get("colorControl").combineCommands(source.get("colorControl"));
    destination.get("ballastConfiguration").combineCommands(source.get("ballastConfiguration"));
    destination.get("illuminanceMeasurement").combineCommands(source.get("illuminanceMeasurement"));
    destination.get("temperatureMeasurement").combineCommands(source.get("temperatureMeasurement"));
    destination.get("pressureMeasurement").combineCommands(source.get("pressureMeasurement"));
    destination.get("flowMeasurement").combineCommands(source.get("flowMeasurement"));
    destination
        .get("relativeHumidityMeasurement")
        .combineCommands(source.get("relativeHumidityMeasurement"));
    destination.get("occupancySensing").combineCommands(source.get("occupancySensing"));
    destination.get("wakeOnLan").combineCommands(source.get("wakeOnLan"));
    destination.get("channel").combineCommands(source.get("channel"));
    destination.get("targetNavigator").combineCommands(source.get("targetNavigator"));
    destination.get("mediaPlayback").combineCommands(source.get("mediaPlayback"));
    destination.get("mediaInput").combineCommands(source.get("mediaInput"));
    destination.get("lowPower").combineCommands(source.get("lowPower"));
    destination.get("keypadInput").combineCommands(source.get("keypadInput"));
    destination.get("contentLauncher").combineCommands(source.get("contentLauncher"));
    destination.get("audioOutput").combineCommands(source.get("audioOutput"));
    destination.get("applicationLauncher").combineCommands(source.get("applicationLauncher"));
    destination.get("applicationBasic").combineCommands(source.get("applicationBasic"));
    destination.get("accountLogin").combineCommands(source.get("accountLogin"));
    destination.get("electricalMeasurement").combineCommands(source.get("electricalMeasurement"));
    destination.get("unitTesting").combineCommands(source.get("unitTesting"));
    destination.get("faultInjection").combineCommands(source.get("faultInjection"));
  }

  @SuppressWarnings("unchecked")
  public Map<String, Map<String, InteractionInfo>> getCommandMap() {
    Map<String, Map<String, InteractionInfo>> commandMap = new HashMap<>();
    Map<String, InteractionInfo> identifyClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> identifyidentifyCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo identifyidentifyidentifyTimeCommandParameterInfo =
        new CommandParameterInfo("identifyTime", Integer.class, Integer.class);
    identifyidentifyCommandParams.put(
        "identifyTime", identifyidentifyidentifyTimeCommandParameterInfo);

    InteractionInfo identifyidentifyInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.IdentifyCluster) cluster)
                  .identify(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("identifyTime"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            identifyidentifyCommandParams);
    identifyClusterInteractionInfoMap.put("identify", identifyidentifyInteractionInfo);
    Map<String, CommandParameterInfo> identifytriggerEffectCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo identifytriggerEffecteffectIdentifierCommandParameterInfo =
        new CommandParameterInfo("effectIdentifier", Integer.class, Integer.class);
    identifytriggerEffectCommandParams.put(
        "effectIdentifier", identifytriggerEffecteffectIdentifierCommandParameterInfo);

    CommandParameterInfo identifytriggerEffecteffectVariantCommandParameterInfo =
        new CommandParameterInfo("effectVariant", Integer.class, Integer.class);
    identifytriggerEffectCommandParams.put(
        "effectVariant", identifytriggerEffecteffectVariantCommandParameterInfo);

    InteractionInfo identifytriggerEffectInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.IdentifyCluster) cluster)
                  .triggerEffect(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("effectIdentifier"),
                      (Integer) commandArguments.get("effectVariant"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            identifytriggerEffectCommandParams);
    identifyClusterInteractionInfoMap.put("triggerEffect", identifytriggerEffectInteractionInfo);
    commandMap.put("identify", identifyClusterInteractionInfoMap);
    Map<String, InteractionInfo> groupsClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> groupsaddGroupCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupsaddGroupgroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    groupsaddGroupCommandParams.put("groupID", groupsaddGroupgroupIDCommandParameterInfo);

    CommandParameterInfo groupsaddGroupgroupNameCommandParameterInfo =
        new CommandParameterInfo("groupName", String.class, String.class);
    groupsaddGroupCommandParams.put("groupName", groupsaddGroupgroupNameCommandParameterInfo);

    InteractionInfo groupsaddGroupInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .addGroup(
                      (ChipClusters.GroupsCluster.AddGroupResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"),
                      (String) commandArguments.get("groupName"));
            },
            () -> new DelegatedGroupsClusterAddGroupResponseCallback(),
            groupsaddGroupCommandParams);
    groupsClusterInteractionInfoMap.put("addGroup", groupsaddGroupInteractionInfo);
    Map<String, CommandParameterInfo> groupsviewGroupCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupsviewGroupgroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    groupsviewGroupCommandParams.put("groupID", groupsviewGroupgroupIDCommandParameterInfo);

    InteractionInfo groupsviewGroupInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .viewGroup(
                      (ChipClusters.GroupsCluster.ViewGroupResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"));
            },
            () -> new DelegatedGroupsClusterViewGroupResponseCallback(),
            groupsviewGroupCommandParams);
    groupsClusterInteractionInfoMap.put("viewGroup", groupsviewGroupInteractionInfo);
    Map<String, CommandParameterInfo> groupsgetGroupMembershipCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupsgetGroupMembershipgroupListCommandParameterInfo =
        new CommandParameterInfo("groupList", ArrayList.class, Integer.class);
    groupsgetGroupMembershipCommandParams.put(
        "groupList", groupsgetGroupMembershipgroupListCommandParameterInfo);

    InteractionInfo groupsgetGroupMembershipInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .getGroupMembership(
                      (ChipClusters.GroupsCluster.GetGroupMembershipResponseCallback) callback,
                      (ArrayList<Integer>) commandArguments.get("groupList"));
            },
            () -> new DelegatedGroupsClusterGetGroupMembershipResponseCallback(),
            groupsgetGroupMembershipCommandParams);
    groupsClusterInteractionInfoMap.put(
        "getGroupMembership", groupsgetGroupMembershipInteractionInfo);
    Map<String, CommandParameterInfo> groupsremoveGroupCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupsremoveGroupgroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    groupsremoveGroupCommandParams.put("groupID", groupsremoveGroupgroupIDCommandParameterInfo);

    InteractionInfo groupsremoveGroupInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .removeGroup(
                      (ChipClusters.GroupsCluster.RemoveGroupResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"));
            },
            () -> new DelegatedGroupsClusterRemoveGroupResponseCallback(),
            groupsremoveGroupCommandParams);
    groupsClusterInteractionInfoMap.put("removeGroup", groupsremoveGroupInteractionInfo);
    Map<String, CommandParameterInfo> groupsremoveAllGroupsCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo groupsremoveAllGroupsInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .removeAllGroups((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            groupsremoveAllGroupsCommandParams);
    groupsClusterInteractionInfoMap.put("removeAllGroups", groupsremoveAllGroupsInteractionInfo);
    Map<String, CommandParameterInfo> groupsaddGroupIfIdentifyingCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupsaddGroupIfIdentifyinggroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    groupsaddGroupIfIdentifyingCommandParams.put(
        "groupID", groupsaddGroupIfIdentifyinggroupIDCommandParameterInfo);

    CommandParameterInfo groupsaddGroupIfIdentifyinggroupNameCommandParameterInfo =
        new CommandParameterInfo("groupName", String.class, String.class);
    groupsaddGroupIfIdentifyingCommandParams.put(
        "groupName", groupsaddGroupIfIdentifyinggroupNameCommandParameterInfo);

    InteractionInfo groupsaddGroupIfIdentifyingInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .addGroupIfIdentifying(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("groupID"),
                      (String) commandArguments.get("groupName"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            groupsaddGroupIfIdentifyingCommandParams);
    groupsClusterInteractionInfoMap.put(
        "addGroupIfIdentifying", groupsaddGroupIfIdentifyingInteractionInfo);
    commandMap.put("groups", groupsClusterInteractionInfoMap);
    Map<String, InteractionInfo> scenesClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> scenesaddSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesaddScenegroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    scenesaddSceneCommandParams.put("groupID", scenesaddScenegroupIDCommandParameterInfo);

    CommandParameterInfo scenesaddScenesceneIDCommandParameterInfo =
        new CommandParameterInfo("sceneID", Integer.class, Integer.class);
    scenesaddSceneCommandParams.put("sceneID", scenesaddScenesceneIDCommandParameterInfo);

    CommandParameterInfo scenesaddScenetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    scenesaddSceneCommandParams.put(
        "transitionTime", scenesaddScenetransitionTimeCommandParameterInfo);

    CommandParameterInfo scenesaddScenesceneNameCommandParameterInfo =
        new CommandParameterInfo("sceneName", String.class, String.class);
    scenesaddSceneCommandParams.put("sceneName", scenesaddScenesceneNameCommandParameterInfo);

    InteractionInfo scenesaddSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .addScene(
                      (ChipClusters.ScenesCluster.AddSceneResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"),
                      (Integer) commandArguments.get("sceneID"),
                      (Integer) commandArguments.get("transitionTime"),
                      (String) commandArguments.get("sceneName"),
                      (ArrayList<ChipStructs.ScenesClusterExtensionFieldSet>)
                          commandArguments.get("extensionFieldSets"));
            },
            () -> new DelegatedScenesClusterAddSceneResponseCallback(),
            scenesaddSceneCommandParams);
    scenesClusterInteractionInfoMap.put("addScene", scenesaddSceneInteractionInfo);
    Map<String, CommandParameterInfo> scenesviewSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesviewScenegroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    scenesviewSceneCommandParams.put("groupID", scenesviewScenegroupIDCommandParameterInfo);

    CommandParameterInfo scenesviewScenesceneIDCommandParameterInfo =
        new CommandParameterInfo("sceneID", Integer.class, Integer.class);
    scenesviewSceneCommandParams.put("sceneID", scenesviewScenesceneIDCommandParameterInfo);

    InteractionInfo scenesviewSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .viewScene(
                      (ChipClusters.ScenesCluster.ViewSceneResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"),
                      (Integer) commandArguments.get("sceneID"));
            },
            () -> new DelegatedScenesClusterViewSceneResponseCallback(),
            scenesviewSceneCommandParams);
    scenesClusterInteractionInfoMap.put("viewScene", scenesviewSceneInteractionInfo);
    Map<String, CommandParameterInfo> scenesremoveSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesremoveScenegroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    scenesremoveSceneCommandParams.put("groupID", scenesremoveScenegroupIDCommandParameterInfo);

    CommandParameterInfo scenesremoveScenesceneIDCommandParameterInfo =
        new CommandParameterInfo("sceneID", Integer.class, Integer.class);
    scenesremoveSceneCommandParams.put("sceneID", scenesremoveScenesceneIDCommandParameterInfo);

    InteractionInfo scenesremoveSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .removeScene(
                      (ChipClusters.ScenesCluster.RemoveSceneResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"),
                      (Integer) commandArguments.get("sceneID"));
            },
            () -> new DelegatedScenesClusterRemoveSceneResponseCallback(),
            scenesremoveSceneCommandParams);
    scenesClusterInteractionInfoMap.put("removeScene", scenesremoveSceneInteractionInfo);
    Map<String, CommandParameterInfo> scenesremoveAllScenesCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesremoveAllScenesgroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    scenesremoveAllScenesCommandParams.put(
        "groupID", scenesremoveAllScenesgroupIDCommandParameterInfo);

    InteractionInfo scenesremoveAllScenesInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .removeAllScenes(
                      (ChipClusters.ScenesCluster.RemoveAllScenesResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"));
            },
            () -> new DelegatedScenesClusterRemoveAllScenesResponseCallback(),
            scenesremoveAllScenesCommandParams);
    scenesClusterInteractionInfoMap.put("removeAllScenes", scenesremoveAllScenesInteractionInfo);
    Map<String, CommandParameterInfo> scenesstoreSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesstoreScenegroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    scenesstoreSceneCommandParams.put("groupID", scenesstoreScenegroupIDCommandParameterInfo);

    CommandParameterInfo scenesstoreScenesceneIDCommandParameterInfo =
        new CommandParameterInfo("sceneID", Integer.class, Integer.class);
    scenesstoreSceneCommandParams.put("sceneID", scenesstoreScenesceneIDCommandParameterInfo);

    InteractionInfo scenesstoreSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .storeScene(
                      (ChipClusters.ScenesCluster.StoreSceneResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"),
                      (Integer) commandArguments.get("sceneID"));
            },
            () -> new DelegatedScenesClusterStoreSceneResponseCallback(),
            scenesstoreSceneCommandParams);
    scenesClusterInteractionInfoMap.put("storeScene", scenesstoreSceneInteractionInfo);
    Map<String, CommandParameterInfo> scenesrecallSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesrecallScenegroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    scenesrecallSceneCommandParams.put("groupID", scenesrecallScenegroupIDCommandParameterInfo);

    CommandParameterInfo scenesrecallScenesceneIDCommandParameterInfo =
        new CommandParameterInfo("sceneID", Integer.class, Integer.class);
    scenesrecallSceneCommandParams.put("sceneID", scenesrecallScenesceneIDCommandParameterInfo);

    CommandParameterInfo scenesrecallScenetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Optional.class, Integer.class);
    scenesrecallSceneCommandParams.put(
        "transitionTime", scenesrecallScenetransitionTimeCommandParameterInfo);

    InteractionInfo scenesrecallSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .recallScene(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("groupID"),
                      (Integer) commandArguments.get("sceneID"),
                      (Optional<Integer>) commandArguments.get("transitionTime"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            scenesrecallSceneCommandParams);
    scenesClusterInteractionInfoMap.put("recallScene", scenesrecallSceneInteractionInfo);
    Map<String, CommandParameterInfo> scenesgetSceneMembershipCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesgetSceneMembershipgroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    scenesgetSceneMembershipCommandParams.put(
        "groupID", scenesgetSceneMembershipgroupIDCommandParameterInfo);

    InteractionInfo scenesgetSceneMembershipInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .getSceneMembership(
                      (ChipClusters.ScenesCluster.GetSceneMembershipResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"));
            },
            () -> new DelegatedScenesClusterGetSceneMembershipResponseCallback(),
            scenesgetSceneMembershipCommandParams);
    scenesClusterInteractionInfoMap.put(
        "getSceneMembership", scenesgetSceneMembershipInteractionInfo);
    commandMap.put("scenes", scenesClusterInteractionInfoMap);
    Map<String, InteractionInfo> onOffClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> onOffoffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo onOffoffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster).off((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOffoffCommandParams);
    onOffClusterInteractionInfoMap.put("off", onOffoffInteractionInfo);
    Map<String, CommandParameterInfo> onOffonCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo onOffonInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster).on((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOffonCommandParams);
    onOffClusterInteractionInfoMap.put("on", onOffonInteractionInfo);
    Map<String, CommandParameterInfo> onOfftoggleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo onOfftoggleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster).toggle((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOfftoggleCommandParams);
    onOffClusterInteractionInfoMap.put("toggle", onOfftoggleInteractionInfo);
    Map<String, CommandParameterInfo> onOffoffWithEffectCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo onOffoffWithEffecteffectIdentifierCommandParameterInfo =
        new CommandParameterInfo("effectIdentifier", Integer.class, Integer.class);
    onOffoffWithEffectCommandParams.put(
        "effectIdentifier", onOffoffWithEffecteffectIdentifierCommandParameterInfo);

    CommandParameterInfo onOffoffWithEffecteffectVariantCommandParameterInfo =
        new CommandParameterInfo("effectVariant", Integer.class, Integer.class);
    onOffoffWithEffectCommandParams.put(
        "effectVariant", onOffoffWithEffecteffectVariantCommandParameterInfo);

    InteractionInfo onOffoffWithEffectInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster)
                  .offWithEffect(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("effectIdentifier"),
                      (Integer) commandArguments.get("effectVariant"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOffoffWithEffectCommandParams);
    onOffClusterInteractionInfoMap.put("offWithEffect", onOffoffWithEffectInteractionInfo);
    Map<String, CommandParameterInfo> onOffonWithRecallGlobalSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo onOffonWithRecallGlobalSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster)
                  .onWithRecallGlobalScene((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOffonWithRecallGlobalSceneCommandParams);
    onOffClusterInteractionInfoMap.put(
        "onWithRecallGlobalScene", onOffonWithRecallGlobalSceneInteractionInfo);
    Map<String, CommandParameterInfo> onOffonWithTimedOffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo onOffonWithTimedOffonOffControlCommandParameterInfo =
        new CommandParameterInfo("onOffControl", Integer.class, Integer.class);
    onOffonWithTimedOffCommandParams.put(
        "onOffControl", onOffonWithTimedOffonOffControlCommandParameterInfo);

    CommandParameterInfo onOffonWithTimedOffonTimeCommandParameterInfo =
        new CommandParameterInfo("onTime", Integer.class, Integer.class);
    onOffonWithTimedOffCommandParams.put("onTime", onOffonWithTimedOffonTimeCommandParameterInfo);

    CommandParameterInfo onOffonWithTimedOffoffWaitTimeCommandParameterInfo =
        new CommandParameterInfo("offWaitTime", Integer.class, Integer.class);
    onOffonWithTimedOffCommandParams.put(
        "offWaitTime", onOffonWithTimedOffoffWaitTimeCommandParameterInfo);

    InteractionInfo onOffonWithTimedOffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster)
                  .onWithTimedOff(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("onOffControl"),
                      (Integer) commandArguments.get("onTime"),
                      (Integer) commandArguments.get("offWaitTime"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOffonWithTimedOffCommandParams);
    onOffClusterInteractionInfoMap.put("onWithTimedOff", onOffonWithTimedOffInteractionInfo);
    commandMap.put("onOff", onOffClusterInteractionInfoMap);
    Map<String, InteractionInfo> onOffSwitchConfigurationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("onOffSwitchConfiguration", onOffSwitchConfigurationClusterInteractionInfoMap);
    Map<String, InteractionInfo> levelControlClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> levelControlmoveToLevelCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlmoveToLevellevelCommandParameterInfo =
        new CommandParameterInfo("level", Integer.class, Integer.class);
    levelControlmoveToLevelCommandParams.put(
        "level", levelControlmoveToLevellevelCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLeveltransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    levelControlmoveToLevelCommandParams.put(
        "transitionTime", levelControlmoveToLeveltransitionTimeCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLeveloptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlmoveToLevelCommandParams.put(
        "optionsMask", levelControlmoveToLeveloptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLeveloptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlmoveToLevelCommandParams.put(
        "optionsOverride", levelControlmoveToLeveloptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlmoveToLevelInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .moveToLevel(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("level"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlmoveToLevelCommandParams);
    levelControlClusterInteractionInfoMap.put(
        "moveToLevel", levelControlmoveToLevelInteractionInfo);
    Map<String, CommandParameterInfo> levelControlmoveCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlmovemoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    levelControlmoveCommandParams.put("moveMode", levelControlmovemoveModeCommandParameterInfo);

    CommandParameterInfo levelControlmoverateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    levelControlmoveCommandParams.put("rate", levelControlmoverateCommandParameterInfo);

    CommandParameterInfo levelControlmoveoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlmoveCommandParams.put(
        "optionsMask", levelControlmoveoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlmoveoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlmoveCommandParams.put(
        "optionsOverride", levelControlmoveoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlmoveInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .move(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlmoveCommandParams);
    levelControlClusterInteractionInfoMap.put("move", levelControlmoveInteractionInfo);
    Map<String, CommandParameterInfo> levelControlstepCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlstepstepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    levelControlstepCommandParams.put("stepMode", levelControlstepstepModeCommandParameterInfo);

    CommandParameterInfo levelControlstepstepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    levelControlstepCommandParams.put("stepSize", levelControlstepstepSizeCommandParameterInfo);

    CommandParameterInfo levelControlsteptransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    levelControlstepCommandParams.put(
        "transitionTime", levelControlsteptransitionTimeCommandParameterInfo);

    CommandParameterInfo levelControlstepoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlstepCommandParams.put(
        "optionsMask", levelControlstepoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlstepoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlstepCommandParams.put(
        "optionsOverride", levelControlstepoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlstepInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .step(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlstepCommandParams);
    levelControlClusterInteractionInfoMap.put("step", levelControlstepInteractionInfo);
    Map<String, CommandParameterInfo> levelControlstopCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlstopoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlstopCommandParams.put(
        "optionsMask", levelControlstopoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlstopoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlstopCommandParams.put(
        "optionsOverride", levelControlstopoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlstopInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .stop(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlstopCommandParams);
    levelControlClusterInteractionInfoMap.put("stop", levelControlstopInteractionInfo);
    Map<String, CommandParameterInfo> levelControlmoveToLevelWithOnOffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlmoveToLevelWithOnOfflevelCommandParameterInfo =
        new CommandParameterInfo("level", Integer.class, Integer.class);
    levelControlmoveToLevelWithOnOffCommandParams.put(
        "level", levelControlmoveToLevelWithOnOfflevelCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLevelWithOnOfftransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    levelControlmoveToLevelWithOnOffCommandParams.put(
        "transitionTime", levelControlmoveToLevelWithOnOfftransitionTimeCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLevelWithOnOffoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlmoveToLevelWithOnOffCommandParams.put(
        "optionsMask", levelControlmoveToLevelWithOnOffoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLevelWithOnOffoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlmoveToLevelWithOnOffCommandParams.put(
        "optionsOverride", levelControlmoveToLevelWithOnOffoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlmoveToLevelWithOnOffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .moveToLevelWithOnOff(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("level"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlmoveToLevelWithOnOffCommandParams);
    levelControlClusterInteractionInfoMap.put(
        "moveToLevelWithOnOff", levelControlmoveToLevelWithOnOffInteractionInfo);
    Map<String, CommandParameterInfo> levelControlmoveWithOnOffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlmoveWithOnOffmoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    levelControlmoveWithOnOffCommandParams.put(
        "moveMode", levelControlmoveWithOnOffmoveModeCommandParameterInfo);

    CommandParameterInfo levelControlmoveWithOnOffrateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    levelControlmoveWithOnOffCommandParams.put(
        "rate", levelControlmoveWithOnOffrateCommandParameterInfo);

    CommandParameterInfo levelControlmoveWithOnOffoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlmoveWithOnOffCommandParams.put(
        "optionsMask", levelControlmoveWithOnOffoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlmoveWithOnOffoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlmoveWithOnOffCommandParams.put(
        "optionsOverride", levelControlmoveWithOnOffoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlmoveWithOnOffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .moveWithOnOff(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlmoveWithOnOffCommandParams);
    levelControlClusterInteractionInfoMap.put(
        "moveWithOnOff", levelControlmoveWithOnOffInteractionInfo);
    Map<String, CommandParameterInfo> levelControlstepWithOnOffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlstepWithOnOffstepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    levelControlstepWithOnOffCommandParams.put(
        "stepMode", levelControlstepWithOnOffstepModeCommandParameterInfo);

    CommandParameterInfo levelControlstepWithOnOffstepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    levelControlstepWithOnOffCommandParams.put(
        "stepSize", levelControlstepWithOnOffstepSizeCommandParameterInfo);

    CommandParameterInfo levelControlstepWithOnOfftransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    levelControlstepWithOnOffCommandParams.put(
        "transitionTime", levelControlstepWithOnOfftransitionTimeCommandParameterInfo);

    CommandParameterInfo levelControlstepWithOnOffoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlstepWithOnOffCommandParams.put(
        "optionsMask", levelControlstepWithOnOffoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlstepWithOnOffoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlstepWithOnOffCommandParams.put(
        "optionsOverride", levelControlstepWithOnOffoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlstepWithOnOffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .stepWithOnOff(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlstepWithOnOffCommandParams);
    levelControlClusterInteractionInfoMap.put(
        "stepWithOnOff", levelControlstepWithOnOffInteractionInfo);
    Map<String, CommandParameterInfo> levelControlstopWithOnOffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlstopWithOnOffoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlstopWithOnOffCommandParams.put(
        "optionsMask", levelControlstopWithOnOffoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlstopWithOnOffoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlstopWithOnOffCommandParams.put(
        "optionsOverride", levelControlstopWithOnOffoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlstopWithOnOffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .stopWithOnOff(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlstopWithOnOffCommandParams);
    levelControlClusterInteractionInfoMap.put(
        "stopWithOnOff", levelControlstopWithOnOffInteractionInfo);
    commandMap.put("levelControl", levelControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> binaryInputBasicClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("binaryInputBasic", binaryInputBasicClusterInteractionInfoMap);
    Map<String, InteractionInfo> pulseWidthModulationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("pulseWidthModulation", pulseWidthModulationClusterInteractionInfoMap);
    Map<String, InteractionInfo> descriptorClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("descriptor", descriptorClusterInteractionInfoMap);
    Map<String, InteractionInfo> bindingClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("binding", bindingClusterInteractionInfoMap);
    Map<String, InteractionInfo> accessControlClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("accessControl", accessControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> actionsClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> actionsinstantActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsinstantActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsinstantActionCommandParams.put(
        "actionID", actionsinstantActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsinstantActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsinstantActionCommandParams.put(
        "invokeID", actionsinstantActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsinstantActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .instantAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsinstantActionCommandParams);
    actionsClusterInteractionInfoMap.put("instantAction", actionsinstantActionInteractionInfo);
    Map<String, CommandParameterInfo> actionsinstantActionWithTransitionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsinstantActionWithTransitionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsinstantActionWithTransitionCommandParams.put(
        "actionID", actionsinstantActionWithTransitionactionIDCommandParameterInfo);

    CommandParameterInfo actionsinstantActionWithTransitioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsinstantActionWithTransitionCommandParams.put(
        "invokeID", actionsinstantActionWithTransitioninvokeIDCommandParameterInfo);

    CommandParameterInfo actionsinstantActionWithTransitiontransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    actionsinstantActionWithTransitionCommandParams.put(
        "transitionTime", actionsinstantActionWithTransitiontransitionTimeCommandParameterInfo);

    InteractionInfo actionsinstantActionWithTransitionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .instantActionWithTransition(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Integer) commandArguments.get("transitionTime"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsinstantActionWithTransitionCommandParams);
    actionsClusterInteractionInfoMap.put(
        "instantActionWithTransition", actionsinstantActionWithTransitionInteractionInfo);
    Map<String, CommandParameterInfo> actionsstartActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsstartActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsstartActionCommandParams.put("actionID", actionsstartActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsstartActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsstartActionCommandParams.put("invokeID", actionsstartActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsstartActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .startAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsstartActionCommandParams);
    actionsClusterInteractionInfoMap.put("startAction", actionsstartActionInteractionInfo);
    Map<String, CommandParameterInfo> actionsstartActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsstartActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsstartActionWithDurationCommandParams.put(
        "actionID", actionsstartActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo actionsstartActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsstartActionWithDurationCommandParams.put(
        "invokeID", actionsstartActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo actionsstartActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    actionsstartActionWithDurationCommandParams.put(
        "duration", actionsstartActionWithDurationdurationCommandParameterInfo);

    InteractionInfo actionsstartActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .startActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsstartActionWithDurationCommandParams);
    actionsClusterInteractionInfoMap.put(
        "startActionWithDuration", actionsstartActionWithDurationInteractionInfo);
    Map<String, CommandParameterInfo> actionsstopActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsstopActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsstopActionCommandParams.put("actionID", actionsstopActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsstopActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsstopActionCommandParams.put("invokeID", actionsstopActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsstopActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .stopAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsstopActionCommandParams);
    actionsClusterInteractionInfoMap.put("stopAction", actionsstopActionInteractionInfo);
    Map<String, CommandParameterInfo> actionspauseActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionspauseActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionspauseActionCommandParams.put("actionID", actionspauseActionactionIDCommandParameterInfo);

    CommandParameterInfo actionspauseActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionspauseActionCommandParams.put("invokeID", actionspauseActioninvokeIDCommandParameterInfo);

    InteractionInfo actionspauseActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .pauseAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionspauseActionCommandParams);
    actionsClusterInteractionInfoMap.put("pauseAction", actionspauseActionInteractionInfo);
    Map<String, CommandParameterInfo> actionspauseActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionspauseActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionspauseActionWithDurationCommandParams.put(
        "actionID", actionspauseActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo actionspauseActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionspauseActionWithDurationCommandParams.put(
        "invokeID", actionspauseActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo actionspauseActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    actionspauseActionWithDurationCommandParams.put(
        "duration", actionspauseActionWithDurationdurationCommandParameterInfo);

    InteractionInfo actionspauseActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .pauseActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionspauseActionWithDurationCommandParams);
    actionsClusterInteractionInfoMap.put(
        "pauseActionWithDuration", actionspauseActionWithDurationInteractionInfo);
    Map<String, CommandParameterInfo> actionsresumeActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsresumeActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsresumeActionCommandParams.put(
        "actionID", actionsresumeActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsresumeActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsresumeActionCommandParams.put(
        "invokeID", actionsresumeActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsresumeActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .resumeAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsresumeActionCommandParams);
    actionsClusterInteractionInfoMap.put("resumeAction", actionsresumeActionInteractionInfo);
    Map<String, CommandParameterInfo> actionsenableActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsenableActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsenableActionCommandParams.put(
        "actionID", actionsenableActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsenableActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsenableActionCommandParams.put(
        "invokeID", actionsenableActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsenableActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .enableAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsenableActionCommandParams);
    actionsClusterInteractionInfoMap.put("enableAction", actionsenableActionInteractionInfo);
    Map<String, CommandParameterInfo> actionsenableActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsenableActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsenableActionWithDurationCommandParams.put(
        "actionID", actionsenableActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo actionsenableActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsenableActionWithDurationCommandParams.put(
        "invokeID", actionsenableActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo actionsenableActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    actionsenableActionWithDurationCommandParams.put(
        "duration", actionsenableActionWithDurationdurationCommandParameterInfo);

    InteractionInfo actionsenableActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .enableActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsenableActionWithDurationCommandParams);
    actionsClusterInteractionInfoMap.put(
        "enableActionWithDuration", actionsenableActionWithDurationInteractionInfo);
    Map<String, CommandParameterInfo> actionsdisableActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsdisableActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsdisableActionCommandParams.put(
        "actionID", actionsdisableActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsdisableActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsdisableActionCommandParams.put(
        "invokeID", actionsdisableActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsdisableActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .disableAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsdisableActionCommandParams);
    actionsClusterInteractionInfoMap.put("disableAction", actionsdisableActionInteractionInfo);
    Map<String, CommandParameterInfo> actionsdisableActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsdisableActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsdisableActionWithDurationCommandParams.put(
        "actionID", actionsdisableActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo actionsdisableActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsdisableActionWithDurationCommandParams.put(
        "invokeID", actionsdisableActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo actionsdisableActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    actionsdisableActionWithDurationCommandParams.put(
        "duration", actionsdisableActionWithDurationdurationCommandParameterInfo);

    InteractionInfo actionsdisableActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .disableActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsdisableActionWithDurationCommandParams);
    actionsClusterInteractionInfoMap.put(
        "disableActionWithDuration", actionsdisableActionWithDurationInteractionInfo);
    commandMap.put("actions", actionsClusterInteractionInfoMap);
    Map<String, InteractionInfo> basicInformationClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("basicInformation", basicInformationClusterInteractionInfoMap);
    Map<String, InteractionInfo> otaSoftwareUpdateProviderClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> otaSoftwareUpdateProviderqueryImageCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo otaSoftwareUpdateProviderqueryImagevendorIDCommandParameterInfo =
        new CommandParameterInfo("vendorID", Integer.class, Integer.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "vendorID", otaSoftwareUpdateProviderqueryImagevendorIDCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderqueryImageproductIDCommandParameterInfo =
        new CommandParameterInfo("productID", Integer.class, Integer.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "productID", otaSoftwareUpdateProviderqueryImageproductIDCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderqueryImagesoftwareVersionCommandParameterInfo =
        new CommandParameterInfo("softwareVersion", Long.class, Long.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "softwareVersion", otaSoftwareUpdateProviderqueryImagesoftwareVersionCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderqueryImageprotocolsSupportedCommandParameterInfo =
        new CommandParameterInfo("protocolsSupported", ArrayList.class, Integer.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "protocolsSupported",
        otaSoftwareUpdateProviderqueryImageprotocolsSupportedCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderqueryImagehardwareVersionCommandParameterInfo =
        new CommandParameterInfo("hardwareVersion", Optional.class, Integer.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "hardwareVersion", otaSoftwareUpdateProviderqueryImagehardwareVersionCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderqueryImagelocationCommandParameterInfo =
        new CommandParameterInfo("location", Optional.class, String.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "location", otaSoftwareUpdateProviderqueryImagelocationCommandParameterInfo);

    CommandParameterInfo
        otaSoftwareUpdateProviderqueryImagerequestorCanConsentCommandParameterInfo =
            new CommandParameterInfo("requestorCanConsent", Optional.class, Boolean.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "requestorCanConsent",
        otaSoftwareUpdateProviderqueryImagerequestorCanConsentCommandParameterInfo);

    CommandParameterInfo
        otaSoftwareUpdateProviderqueryImagemetadataForProviderCommandParameterInfo =
            new CommandParameterInfo("metadataForProvider", Optional.class, byte[].class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "metadataForProvider",
        otaSoftwareUpdateProviderqueryImagemetadataForProviderCommandParameterInfo);

    InteractionInfo otaSoftwareUpdateProviderqueryImageInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OtaSoftwareUpdateProviderCluster) cluster)
                  .queryImage(
                      (ChipClusters.OtaSoftwareUpdateProviderCluster.QueryImageResponseCallback)
                          callback,
                      (Integer) commandArguments.get("vendorID"),
                      (Integer) commandArguments.get("productID"),
                      (Long) commandArguments.get("softwareVersion"),
                      (ArrayList<Integer>) commandArguments.get("protocolsSupported"),
                      (Optional<Integer>) commandArguments.get("hardwareVersion"),
                      (Optional<String>) commandArguments.get("location"),
                      (Optional<Boolean>) commandArguments.get("requestorCanConsent"),
                      (Optional<byte[]>) commandArguments.get("metadataForProvider"));
            },
            () -> new DelegatedOtaSoftwareUpdateProviderClusterQueryImageResponseCallback(),
            otaSoftwareUpdateProviderqueryImageCommandParams);
    otaSoftwareUpdateProviderClusterInteractionInfoMap.put(
        "queryImage", otaSoftwareUpdateProviderqueryImageInteractionInfo);
    Map<String, CommandParameterInfo> otaSoftwareUpdateProviderapplyUpdateRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        otaSoftwareUpdateProviderapplyUpdateRequestupdateTokenCommandParameterInfo =
            new CommandParameterInfo("updateToken", byte[].class, byte[].class);
    otaSoftwareUpdateProviderapplyUpdateRequestCommandParams.put(
        "updateToken", otaSoftwareUpdateProviderapplyUpdateRequestupdateTokenCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderapplyUpdateRequestnewVersionCommandParameterInfo =
        new CommandParameterInfo("newVersion", Long.class, Long.class);
    otaSoftwareUpdateProviderapplyUpdateRequestCommandParams.put(
        "newVersion", otaSoftwareUpdateProviderapplyUpdateRequestnewVersionCommandParameterInfo);

    InteractionInfo otaSoftwareUpdateProviderapplyUpdateRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OtaSoftwareUpdateProviderCluster) cluster)
                  .applyUpdateRequest(
                      (ChipClusters.OtaSoftwareUpdateProviderCluster.ApplyUpdateResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("updateToken"),
                      (Long) commandArguments.get("newVersion"));
            },
            () -> new DelegatedOtaSoftwareUpdateProviderClusterApplyUpdateResponseCallback(),
            otaSoftwareUpdateProviderapplyUpdateRequestCommandParams);
    otaSoftwareUpdateProviderClusterInteractionInfoMap.put(
        "applyUpdateRequest", otaSoftwareUpdateProviderapplyUpdateRequestInteractionInfo);
    Map<String, CommandParameterInfo> otaSoftwareUpdateProvidernotifyUpdateAppliedCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        otaSoftwareUpdateProvidernotifyUpdateAppliedupdateTokenCommandParameterInfo =
            new CommandParameterInfo("updateToken", byte[].class, byte[].class);
    otaSoftwareUpdateProvidernotifyUpdateAppliedCommandParams.put(
        "updateToken", otaSoftwareUpdateProvidernotifyUpdateAppliedupdateTokenCommandParameterInfo);

    CommandParameterInfo
        otaSoftwareUpdateProvidernotifyUpdateAppliedsoftwareVersionCommandParameterInfo =
            new CommandParameterInfo("softwareVersion", Long.class, Long.class);
    otaSoftwareUpdateProvidernotifyUpdateAppliedCommandParams.put(
        "softwareVersion",
        otaSoftwareUpdateProvidernotifyUpdateAppliedsoftwareVersionCommandParameterInfo);

    InteractionInfo otaSoftwareUpdateProvidernotifyUpdateAppliedInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OtaSoftwareUpdateProviderCluster) cluster)
                  .notifyUpdateApplied(
                      (DefaultClusterCallback) callback,
                      (byte[]) commandArguments.get("updateToken"),
                      (Long) commandArguments.get("softwareVersion"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            otaSoftwareUpdateProvidernotifyUpdateAppliedCommandParams);
    otaSoftwareUpdateProviderClusterInteractionInfoMap.put(
        "notifyUpdateApplied", otaSoftwareUpdateProvidernotifyUpdateAppliedInteractionInfo);
    commandMap.put("otaSoftwareUpdateProvider", otaSoftwareUpdateProviderClusterInteractionInfoMap);
    Map<String, InteractionInfo> otaSoftwareUpdateRequestorClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> otaSoftwareUpdateRequestorannounceOTAProviderCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        otaSoftwareUpdateRequestorannounceOTAProviderproviderNodeIDCommandParameterInfo =
            new CommandParameterInfo("providerNodeID", Long.class, Long.class);
    otaSoftwareUpdateRequestorannounceOTAProviderCommandParams.put(
        "providerNodeID",
        otaSoftwareUpdateRequestorannounceOTAProviderproviderNodeIDCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateRequestorannounceOTAProvidervendorIDCommandParameterInfo =
        new CommandParameterInfo("vendorID", Integer.class, Integer.class);
    otaSoftwareUpdateRequestorannounceOTAProviderCommandParams.put(
        "vendorID", otaSoftwareUpdateRequestorannounceOTAProvidervendorIDCommandParameterInfo);

    CommandParameterInfo
        otaSoftwareUpdateRequestorannounceOTAProviderannouncementReasonCommandParameterInfo =
            new CommandParameterInfo("announcementReason", Integer.class, Integer.class);
    otaSoftwareUpdateRequestorannounceOTAProviderCommandParams.put(
        "announcementReason",
        otaSoftwareUpdateRequestorannounceOTAProviderannouncementReasonCommandParameterInfo);

    CommandParameterInfo
        otaSoftwareUpdateRequestorannounceOTAProvidermetadataForNodeCommandParameterInfo =
            new CommandParameterInfo("metadataForNode", Optional.class, byte[].class);
    otaSoftwareUpdateRequestorannounceOTAProviderCommandParams.put(
        "metadataForNode",
        otaSoftwareUpdateRequestorannounceOTAProvidermetadataForNodeCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateRequestorannounceOTAProviderendpointCommandParameterInfo =
        new CommandParameterInfo("endpoint", Integer.class, Integer.class);
    otaSoftwareUpdateRequestorannounceOTAProviderCommandParams.put(
        "endpoint", otaSoftwareUpdateRequestorannounceOTAProviderendpointCommandParameterInfo);

    InteractionInfo otaSoftwareUpdateRequestorannounceOTAProviderInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OtaSoftwareUpdateRequestorCluster) cluster)
                  .announceOTAProvider(
                      (DefaultClusterCallback) callback,
                      (Long) commandArguments.get("providerNodeID"),
                      (Integer) commandArguments.get("vendorID"),
                      (Integer) commandArguments.get("announcementReason"),
                      (Optional<byte[]>) commandArguments.get("metadataForNode"),
                      (Integer) commandArguments.get("endpoint"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            otaSoftwareUpdateRequestorannounceOTAProviderCommandParams);
    otaSoftwareUpdateRequestorClusterInteractionInfoMap.put(
        "announceOTAProvider", otaSoftwareUpdateRequestorannounceOTAProviderInteractionInfo);
    commandMap.put(
        "otaSoftwareUpdateRequestor", otaSoftwareUpdateRequestorClusterInteractionInfoMap);
    Map<String, InteractionInfo> localizationConfigurationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("localizationConfiguration", localizationConfigurationClusterInteractionInfoMap);
    Map<String, InteractionInfo> timeFormatLocalizationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("timeFormatLocalization", timeFormatLocalizationClusterInteractionInfoMap);
    Map<String, InteractionInfo> unitLocalizationClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("unitLocalization", unitLocalizationClusterInteractionInfoMap);
    Map<String, InteractionInfo> powerSourceConfigurationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("powerSourceConfiguration", powerSourceConfigurationClusterInteractionInfoMap);
    Map<String, InteractionInfo> powerSourceClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("powerSource", powerSourceClusterInteractionInfoMap);
    Map<String, InteractionInfo> generalCommissioningClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> generalCommissioningarmFailSafeCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo generalCommissioningarmFailSafeexpiryLengthSecondsCommandParameterInfo =
        new CommandParameterInfo("expiryLengthSeconds", Integer.class, Integer.class);
    generalCommissioningarmFailSafeCommandParams.put(
        "expiryLengthSeconds",
        generalCommissioningarmFailSafeexpiryLengthSecondsCommandParameterInfo);

    CommandParameterInfo generalCommissioningarmFailSafebreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Long.class, Long.class);
    generalCommissioningarmFailSafeCommandParams.put(
        "breadcrumb", generalCommissioningarmFailSafebreadcrumbCommandParameterInfo);

    InteractionInfo generalCommissioningarmFailSafeInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GeneralCommissioningCluster) cluster)
                  .armFailSafe(
                      (ChipClusters.GeneralCommissioningCluster.ArmFailSafeResponseCallback)
                          callback,
                      (Integer) commandArguments.get("expiryLengthSeconds"),
                      (Long) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedGeneralCommissioningClusterArmFailSafeResponseCallback(),
            generalCommissioningarmFailSafeCommandParams);
    generalCommissioningClusterInteractionInfoMap.put(
        "armFailSafe", generalCommissioningarmFailSafeInteractionInfo);
    Map<String, CommandParameterInfo> generalCommissioningsetRegulatoryConfigCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        generalCommissioningsetRegulatoryConfignewRegulatoryConfigCommandParameterInfo =
            new CommandParameterInfo("newRegulatoryConfig", Integer.class, Integer.class);
    generalCommissioningsetRegulatoryConfigCommandParams.put(
        "newRegulatoryConfig",
        generalCommissioningsetRegulatoryConfignewRegulatoryConfigCommandParameterInfo);

    CommandParameterInfo generalCommissioningsetRegulatoryConfigcountryCodeCommandParameterInfo =
        new CommandParameterInfo("countryCode", String.class, String.class);
    generalCommissioningsetRegulatoryConfigCommandParams.put(
        "countryCode", generalCommissioningsetRegulatoryConfigcountryCodeCommandParameterInfo);

    CommandParameterInfo generalCommissioningsetRegulatoryConfigbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Long.class, Long.class);
    generalCommissioningsetRegulatoryConfigCommandParams.put(
        "breadcrumb", generalCommissioningsetRegulatoryConfigbreadcrumbCommandParameterInfo);

    InteractionInfo generalCommissioningsetRegulatoryConfigInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GeneralCommissioningCluster) cluster)
                  .setRegulatoryConfig(
                      (ChipClusters.GeneralCommissioningCluster.SetRegulatoryConfigResponseCallback)
                          callback,
                      (Integer) commandArguments.get("newRegulatoryConfig"),
                      (String) commandArguments.get("countryCode"),
                      (Long) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedGeneralCommissioningClusterSetRegulatoryConfigResponseCallback(),
            generalCommissioningsetRegulatoryConfigCommandParams);
    generalCommissioningClusterInteractionInfoMap.put(
        "setRegulatoryConfig", generalCommissioningsetRegulatoryConfigInteractionInfo);
    Map<String, CommandParameterInfo> generalCommissioningcommissioningCompleteCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo generalCommissioningcommissioningCompleteInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GeneralCommissioningCluster) cluster)
                  .commissioningComplete(
                      (ChipClusters.GeneralCommissioningCluster
                              .CommissioningCompleteResponseCallback)
                          callback);
            },
            () -> new DelegatedGeneralCommissioningClusterCommissioningCompleteResponseCallback(),
            generalCommissioningcommissioningCompleteCommandParams);
    generalCommissioningClusterInteractionInfoMap.put(
        "commissioningComplete", generalCommissioningcommissioningCompleteInteractionInfo);
    commandMap.put("generalCommissioning", generalCommissioningClusterInteractionInfoMap);
    Map<String, InteractionInfo> networkCommissioningClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> networkCommissioningscanNetworksCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo networkCommissioningscanNetworksssidCommandParameterInfo =
        new CommandParameterInfo("ssid", Optional.class, byte[].class);
    networkCommissioningscanNetworksCommandParams.put(
        "ssid", networkCommissioningscanNetworksssidCommandParameterInfo);

    CommandParameterInfo networkCommissioningscanNetworksbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningscanNetworksCommandParams.put(
        "breadcrumb", networkCommissioningscanNetworksbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningscanNetworksInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .scanNetworks(
                      (ChipClusters.NetworkCommissioningCluster.ScanNetworksResponseCallback)
                          callback,
                      (Optional<byte[]>) commandArguments.get("ssid"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedNetworkCommissioningClusterScanNetworksResponseCallback(),
            networkCommissioningscanNetworksCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "scanNetworks", networkCommissioningscanNetworksInteractionInfo);
    Map<String, CommandParameterInfo> networkCommissioningaddOrUpdateWiFiNetworkCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo networkCommissioningaddOrUpdateWiFiNetworkssidCommandParameterInfo =
        new CommandParameterInfo("ssid", byte[].class, byte[].class);
    networkCommissioningaddOrUpdateWiFiNetworkCommandParams.put(
        "ssid", networkCommissioningaddOrUpdateWiFiNetworkssidCommandParameterInfo);

    CommandParameterInfo networkCommissioningaddOrUpdateWiFiNetworkcredentialsCommandParameterInfo =
        new CommandParameterInfo("credentials", byte[].class, byte[].class);
    networkCommissioningaddOrUpdateWiFiNetworkCommandParams.put(
        "credentials", networkCommissioningaddOrUpdateWiFiNetworkcredentialsCommandParameterInfo);

    CommandParameterInfo networkCommissioningaddOrUpdateWiFiNetworkbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningaddOrUpdateWiFiNetworkCommandParams.put(
        "breadcrumb", networkCommissioningaddOrUpdateWiFiNetworkbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningaddOrUpdateWiFiNetworkInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .addOrUpdateWiFiNetwork(
                      (ChipClusters.NetworkCommissioningCluster.NetworkConfigResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("ssid"),
                      (byte[]) commandArguments.get("credentials"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedNetworkCommissioningClusterNetworkConfigResponseCallback(),
            networkCommissioningaddOrUpdateWiFiNetworkCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "addOrUpdateWiFiNetwork", networkCommissioningaddOrUpdateWiFiNetworkInteractionInfo);
    Map<String, CommandParameterInfo> networkCommissioningaddOrUpdateThreadNetworkCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        networkCommissioningaddOrUpdateThreadNetworkoperationalDatasetCommandParameterInfo =
            new CommandParameterInfo("operationalDataset", byte[].class, byte[].class);
    networkCommissioningaddOrUpdateThreadNetworkCommandParams.put(
        "operationalDataset",
        networkCommissioningaddOrUpdateThreadNetworkoperationalDatasetCommandParameterInfo);

    CommandParameterInfo
        networkCommissioningaddOrUpdateThreadNetworkbreadcrumbCommandParameterInfo =
            new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningaddOrUpdateThreadNetworkCommandParams.put(
        "breadcrumb", networkCommissioningaddOrUpdateThreadNetworkbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningaddOrUpdateThreadNetworkInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .addOrUpdateThreadNetwork(
                      (ChipClusters.NetworkCommissioningCluster.NetworkConfigResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("operationalDataset"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedNetworkCommissioningClusterNetworkConfigResponseCallback(),
            networkCommissioningaddOrUpdateThreadNetworkCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "addOrUpdateThreadNetwork", networkCommissioningaddOrUpdateThreadNetworkInteractionInfo);
    Map<String, CommandParameterInfo> networkCommissioningremoveNetworkCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo networkCommissioningremoveNetworknetworkIDCommandParameterInfo =
        new CommandParameterInfo("networkID", byte[].class, byte[].class);
    networkCommissioningremoveNetworkCommandParams.put(
        "networkID", networkCommissioningremoveNetworknetworkIDCommandParameterInfo);

    CommandParameterInfo networkCommissioningremoveNetworkbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningremoveNetworkCommandParams.put(
        "breadcrumb", networkCommissioningremoveNetworkbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningremoveNetworkInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .removeNetwork(
                      (ChipClusters.NetworkCommissioningCluster.NetworkConfigResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("networkID"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedNetworkCommissioningClusterNetworkConfigResponseCallback(),
            networkCommissioningremoveNetworkCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "removeNetwork", networkCommissioningremoveNetworkInteractionInfo);
    Map<String, CommandParameterInfo> networkCommissioningconnectNetworkCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo networkCommissioningconnectNetworknetworkIDCommandParameterInfo =
        new CommandParameterInfo("networkID", byte[].class, byte[].class);
    networkCommissioningconnectNetworkCommandParams.put(
        "networkID", networkCommissioningconnectNetworknetworkIDCommandParameterInfo);

    CommandParameterInfo networkCommissioningconnectNetworkbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningconnectNetworkCommandParams.put(
        "breadcrumb", networkCommissioningconnectNetworkbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningconnectNetworkInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .connectNetwork(
                      (ChipClusters.NetworkCommissioningCluster.ConnectNetworkResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("networkID"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedNetworkCommissioningClusterConnectNetworkResponseCallback(),
            networkCommissioningconnectNetworkCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "connectNetwork", networkCommissioningconnectNetworkInteractionInfo);
    Map<String, CommandParameterInfo> networkCommissioningreorderNetworkCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo networkCommissioningreorderNetworknetworkIDCommandParameterInfo =
        new CommandParameterInfo("networkID", byte[].class, byte[].class);
    networkCommissioningreorderNetworkCommandParams.put(
        "networkID", networkCommissioningreorderNetworknetworkIDCommandParameterInfo);

    CommandParameterInfo networkCommissioningreorderNetworknetworkIndexCommandParameterInfo =
        new CommandParameterInfo("networkIndex", Integer.class, Integer.class);
    networkCommissioningreorderNetworkCommandParams.put(
        "networkIndex", networkCommissioningreorderNetworknetworkIndexCommandParameterInfo);

    CommandParameterInfo networkCommissioningreorderNetworkbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningreorderNetworkCommandParams.put(
        "breadcrumb", networkCommissioningreorderNetworkbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningreorderNetworkInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .reorderNetwork(
                      (ChipClusters.NetworkCommissioningCluster.NetworkConfigResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("networkID"),
                      (Integer) commandArguments.get("networkIndex"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedNetworkCommissioningClusterNetworkConfigResponseCallback(),
            networkCommissioningreorderNetworkCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "reorderNetwork", networkCommissioningreorderNetworkInteractionInfo);
    commandMap.put("networkCommissioning", networkCommissioningClusterInteractionInfoMap);
    Map<String, InteractionInfo> diagnosticLogsClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> diagnosticLogsretrieveLogsRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo diagnosticLogsretrieveLogsRequestintentCommandParameterInfo =
        new CommandParameterInfo("intent", Integer.class, Integer.class);
    diagnosticLogsretrieveLogsRequestCommandParams.put(
        "intent", diagnosticLogsretrieveLogsRequestintentCommandParameterInfo);

    CommandParameterInfo diagnosticLogsretrieveLogsRequestrequestedProtocolCommandParameterInfo =
        new CommandParameterInfo("requestedProtocol", Integer.class, Integer.class);
    diagnosticLogsretrieveLogsRequestCommandParams.put(
        "requestedProtocol",
        diagnosticLogsretrieveLogsRequestrequestedProtocolCommandParameterInfo);

    CommandParameterInfo
        diagnosticLogsretrieveLogsRequesttransferFileDesignatorCommandParameterInfo =
            new CommandParameterInfo("transferFileDesignator", Optional.class, String.class);
    diagnosticLogsretrieveLogsRequestCommandParams.put(
        "transferFileDesignator",
        diagnosticLogsretrieveLogsRequesttransferFileDesignatorCommandParameterInfo);

    InteractionInfo diagnosticLogsretrieveLogsRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DiagnosticLogsCluster) cluster)
                  .retrieveLogsRequest(
                      (ChipClusters.DiagnosticLogsCluster.RetrieveLogsResponseCallback) callback,
                      (Integer) commandArguments.get("intent"),
                      (Integer) commandArguments.get("requestedProtocol"),
                      (Optional<String>) commandArguments.get("transferFileDesignator"));
            },
            () -> new DelegatedDiagnosticLogsClusterRetrieveLogsResponseCallback(),
            diagnosticLogsretrieveLogsRequestCommandParams);
    diagnosticLogsClusterInteractionInfoMap.put(
        "retrieveLogsRequest", diagnosticLogsretrieveLogsRequestInteractionInfo);
    commandMap.put("diagnosticLogs", diagnosticLogsClusterInteractionInfoMap);
    Map<String, InteractionInfo> generalDiagnosticsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> generalDiagnosticstestEventTriggerCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo generalDiagnosticstestEventTriggerenableKeyCommandParameterInfo =
        new CommandParameterInfo("enableKey", byte[].class, byte[].class);
    generalDiagnosticstestEventTriggerCommandParams.put(
        "enableKey", generalDiagnosticstestEventTriggerenableKeyCommandParameterInfo);

    CommandParameterInfo generalDiagnosticstestEventTriggereventTriggerCommandParameterInfo =
        new CommandParameterInfo("eventTrigger", Long.class, Long.class);
    generalDiagnosticstestEventTriggerCommandParams.put(
        "eventTrigger", generalDiagnosticstestEventTriggereventTriggerCommandParameterInfo);

    InteractionInfo generalDiagnosticstestEventTriggerInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GeneralDiagnosticsCluster) cluster)
                  .testEventTrigger(
                      (DefaultClusterCallback) callback,
                      (byte[]) commandArguments.get("enableKey"),
                      (Long) commandArguments.get("eventTrigger"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            generalDiagnosticstestEventTriggerCommandParams);
    generalDiagnosticsClusterInteractionInfoMap.put(
        "testEventTrigger", generalDiagnosticstestEventTriggerInteractionInfo);
    commandMap.put("generalDiagnostics", generalDiagnosticsClusterInteractionInfoMap);
    Map<String, InteractionInfo> softwareDiagnosticsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> softwareDiagnosticsresetWatermarksCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo softwareDiagnosticsresetWatermarksInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.SoftwareDiagnosticsCluster) cluster)
                  .resetWatermarks((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            softwareDiagnosticsresetWatermarksCommandParams);
    softwareDiagnosticsClusterInteractionInfoMap.put(
        "resetWatermarks", softwareDiagnosticsresetWatermarksInteractionInfo);
    commandMap.put("softwareDiagnostics", softwareDiagnosticsClusterInteractionInfoMap);
    Map<String, InteractionInfo> threadNetworkDiagnosticsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> threadNetworkDiagnosticsresetCountsCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo threadNetworkDiagnosticsresetCountsInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ThreadNetworkDiagnosticsCluster) cluster)
                  .resetCounts((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            threadNetworkDiagnosticsresetCountsCommandParams);
    threadNetworkDiagnosticsClusterInteractionInfoMap.put(
        "resetCounts", threadNetworkDiagnosticsresetCountsInteractionInfo);
    commandMap.put("threadNetworkDiagnostics", threadNetworkDiagnosticsClusterInteractionInfoMap);
    Map<String, InteractionInfo> wiFiNetworkDiagnosticsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> wiFiNetworkDiagnosticsresetCountsCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo wiFiNetworkDiagnosticsresetCountsInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WiFiNetworkDiagnosticsCluster) cluster)
                  .resetCounts((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            wiFiNetworkDiagnosticsresetCountsCommandParams);
    wiFiNetworkDiagnosticsClusterInteractionInfoMap.put(
        "resetCounts", wiFiNetworkDiagnosticsresetCountsInteractionInfo);
    commandMap.put("wiFiNetworkDiagnostics", wiFiNetworkDiagnosticsClusterInteractionInfoMap);
    Map<String, InteractionInfo> ethernetNetworkDiagnosticsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> ethernetNetworkDiagnosticsresetCountsCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo ethernetNetworkDiagnosticsresetCountsInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.EthernetNetworkDiagnosticsCluster) cluster)
                  .resetCounts((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            ethernetNetworkDiagnosticsresetCountsCommandParams);
    ethernetNetworkDiagnosticsClusterInteractionInfoMap.put(
        "resetCounts", ethernetNetworkDiagnosticsresetCountsInteractionInfo);
    commandMap.put(
        "ethernetNetworkDiagnostics", ethernetNetworkDiagnosticsClusterInteractionInfoMap);
    Map<String, InteractionInfo> timeSynchronizationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("timeSynchronization", timeSynchronizationClusterInteractionInfoMap);
    Map<String, InteractionInfo> bridgedDeviceBasicInformationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put(
        "bridgedDeviceBasicInformation", bridgedDeviceBasicInformationClusterInteractionInfoMap);
    Map<String, InteractionInfo> switchClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("switch", switchClusterInteractionInfoMap);
    Map<String, InteractionInfo> administratorCommissioningClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo>
        administratorCommissioningopenCommissioningWindowCommandParams =
            new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        administratorCommissioningopenCommissioningWindowcommissioningTimeoutCommandParameterInfo =
            new CommandParameterInfo("commissioningTimeout", Integer.class, Integer.class);
    administratorCommissioningopenCommissioningWindowCommandParams.put(
        "commissioningTimeout",
        administratorCommissioningopenCommissioningWindowcommissioningTimeoutCommandParameterInfo);

    CommandParameterInfo
        administratorCommissioningopenCommissioningWindowPAKEPasscodeVerifierCommandParameterInfo =
            new CommandParameterInfo("PAKEPasscodeVerifier", byte[].class, byte[].class);
    administratorCommissioningopenCommissioningWindowCommandParams.put(
        "PAKEPasscodeVerifier",
        administratorCommissioningopenCommissioningWindowPAKEPasscodeVerifierCommandParameterInfo);

    CommandParameterInfo
        administratorCommissioningopenCommissioningWindowdiscriminatorCommandParameterInfo =
            new CommandParameterInfo("discriminator", Integer.class, Integer.class);
    administratorCommissioningopenCommissioningWindowCommandParams.put(
        "discriminator",
        administratorCommissioningopenCommissioningWindowdiscriminatorCommandParameterInfo);

    CommandParameterInfo
        administratorCommissioningopenCommissioningWindowiterationsCommandParameterInfo =
            new CommandParameterInfo("iterations", Long.class, Long.class);
    administratorCommissioningopenCommissioningWindowCommandParams.put(
        "iterations",
        administratorCommissioningopenCommissioningWindowiterationsCommandParameterInfo);

    CommandParameterInfo administratorCommissioningopenCommissioningWindowsaltCommandParameterInfo =
        new CommandParameterInfo("salt", byte[].class, byte[].class);
    administratorCommissioningopenCommissioningWindowCommandParams.put(
        "salt", administratorCommissioningopenCommissioningWindowsaltCommandParameterInfo);

    InteractionInfo administratorCommissioningopenCommissioningWindowInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AdministratorCommissioningCluster) cluster)
                  .openCommissioningWindow(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("commissioningTimeout"),
                      (byte[]) commandArguments.get("PAKEPasscodeVerifier"),
                      (Integer) commandArguments.get("discriminator"),
                      (Long) commandArguments.get("iterations"),
                      (byte[]) commandArguments.get("salt"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            administratorCommissioningopenCommissioningWindowCommandParams);
    administratorCommissioningClusterInteractionInfoMap.put(
        "openCommissioningWindow",
        administratorCommissioningopenCommissioningWindowInteractionInfo);
    Map<String, CommandParameterInfo>
        administratorCommissioningopenBasicCommissioningWindowCommandParams =
            new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        administratorCommissioningopenBasicCommissioningWindowcommissioningTimeoutCommandParameterInfo =
            new CommandParameterInfo("commissioningTimeout", Integer.class, Integer.class);
    administratorCommissioningopenBasicCommissioningWindowCommandParams.put(
        "commissioningTimeout",
        administratorCommissioningopenBasicCommissioningWindowcommissioningTimeoutCommandParameterInfo);

    InteractionInfo administratorCommissioningopenBasicCommissioningWindowInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AdministratorCommissioningCluster) cluster)
                  .openBasicCommissioningWindow(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("commissioningTimeout"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            administratorCommissioningopenBasicCommissioningWindowCommandParams);
    administratorCommissioningClusterInteractionInfoMap.put(
        "openBasicCommissioningWindow",
        administratorCommissioningopenBasicCommissioningWindowInteractionInfo);
    Map<String, CommandParameterInfo> administratorCommissioningrevokeCommissioningCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo administratorCommissioningrevokeCommissioningInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AdministratorCommissioningCluster) cluster)
                  .revokeCommissioning((DefaultClusterCallback) callback, 10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            administratorCommissioningrevokeCommissioningCommandParams);
    administratorCommissioningClusterInteractionInfoMap.put(
        "revokeCommissioning", administratorCommissioningrevokeCommissioningInteractionInfo);
    commandMap.put(
        "administratorCommissioning", administratorCommissioningClusterInteractionInfoMap);
    Map<String, InteractionInfo> operationalCredentialsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> operationalCredentialsattestationRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        operationalCredentialsattestationRequestattestationNonceCommandParameterInfo =
            new CommandParameterInfo("attestationNonce", byte[].class, byte[].class);
    operationalCredentialsattestationRequestCommandParams.put(
        "attestationNonce",
        operationalCredentialsattestationRequestattestationNonceCommandParameterInfo);

    InteractionInfo operationalCredentialsattestationRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .attestationRequest(
                      (ChipClusters.OperationalCredentialsCluster.AttestationResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("attestationNonce"));
            },
            () -> new DelegatedOperationalCredentialsClusterAttestationResponseCallback(),
            operationalCredentialsattestationRequestCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "attestationRequest", operationalCredentialsattestationRequestInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialscertificateChainRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        operationalCredentialscertificateChainRequestcertificateTypeCommandParameterInfo =
            new CommandParameterInfo("certificateType", Integer.class, Integer.class);
    operationalCredentialscertificateChainRequestCommandParams.put(
        "certificateType",
        operationalCredentialscertificateChainRequestcertificateTypeCommandParameterInfo);

    InteractionInfo operationalCredentialscertificateChainRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .certificateChainRequest(
                      (ChipClusters.OperationalCredentialsCluster.CertificateChainResponseCallback)
                          callback,
                      (Integer) commandArguments.get("certificateType"));
            },
            () -> new DelegatedOperationalCredentialsClusterCertificateChainResponseCallback(),
            operationalCredentialscertificateChainRequestCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "certificateChainRequest", operationalCredentialscertificateChainRequestInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsCSRRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo operationalCredentialsCSRRequestCSRNonceCommandParameterInfo =
        new CommandParameterInfo("CSRNonce", byte[].class, byte[].class);
    operationalCredentialsCSRRequestCommandParams.put(
        "CSRNonce", operationalCredentialsCSRRequestCSRNonceCommandParameterInfo);

    CommandParameterInfo operationalCredentialsCSRRequestisForUpdateNOCCommandParameterInfo =
        new CommandParameterInfo("isForUpdateNOC", Optional.class, Boolean.class);
    operationalCredentialsCSRRequestCommandParams.put(
        "isForUpdateNOC", operationalCredentialsCSRRequestisForUpdateNOCCommandParameterInfo);

    InteractionInfo operationalCredentialsCSRRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .CSRRequest(
                      (ChipClusters.OperationalCredentialsCluster.CSRResponseCallback) callback,
                      (byte[]) commandArguments.get("CSRNonce"),
                      (Optional<Boolean>) commandArguments.get("isForUpdateNOC"));
            },
            () -> new DelegatedOperationalCredentialsClusterCSRResponseCallback(),
            operationalCredentialsCSRRequestCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "CSRRequest", operationalCredentialsCSRRequestInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsaddNOCCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo operationalCredentialsaddNOCNOCValueCommandParameterInfo =
        new CommandParameterInfo("NOCValue", byte[].class, byte[].class);
    operationalCredentialsaddNOCCommandParams.put(
        "NOCValue", operationalCredentialsaddNOCNOCValueCommandParameterInfo);

    CommandParameterInfo operationalCredentialsaddNOCICACValueCommandParameterInfo =
        new CommandParameterInfo("ICACValue", Optional.class, byte[].class);
    operationalCredentialsaddNOCCommandParams.put(
        "ICACValue", operationalCredentialsaddNOCICACValueCommandParameterInfo);

    CommandParameterInfo operationalCredentialsaddNOCIPKValueCommandParameterInfo =
        new CommandParameterInfo("IPKValue", byte[].class, byte[].class);
    operationalCredentialsaddNOCCommandParams.put(
        "IPKValue", operationalCredentialsaddNOCIPKValueCommandParameterInfo);

    CommandParameterInfo operationalCredentialsaddNOCcaseAdminSubjectCommandParameterInfo =
        new CommandParameterInfo("caseAdminSubject", Long.class, Long.class);
    operationalCredentialsaddNOCCommandParams.put(
        "caseAdminSubject", operationalCredentialsaddNOCcaseAdminSubjectCommandParameterInfo);

    CommandParameterInfo operationalCredentialsaddNOCadminVendorIdCommandParameterInfo =
        new CommandParameterInfo("adminVendorId", Integer.class, Integer.class);
    operationalCredentialsaddNOCCommandParams.put(
        "adminVendorId", operationalCredentialsaddNOCadminVendorIdCommandParameterInfo);

    InteractionInfo operationalCredentialsaddNOCInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .addNOC(
                      (ChipClusters.OperationalCredentialsCluster.NOCResponseCallback) callback,
                      (byte[]) commandArguments.get("NOCValue"),
                      (Optional<byte[]>) commandArguments.get("ICACValue"),
                      (byte[]) commandArguments.get("IPKValue"),
                      (Long) commandArguments.get("caseAdminSubject"),
                      (Integer) commandArguments.get("adminVendorId"));
            },
            () -> new DelegatedOperationalCredentialsClusterNOCResponseCallback(),
            operationalCredentialsaddNOCCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "addNOC", operationalCredentialsaddNOCInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsupdateNOCCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo operationalCredentialsupdateNOCNOCValueCommandParameterInfo =
        new CommandParameterInfo("NOCValue", byte[].class, byte[].class);
    operationalCredentialsupdateNOCCommandParams.put(
        "NOCValue", operationalCredentialsupdateNOCNOCValueCommandParameterInfo);

    CommandParameterInfo operationalCredentialsupdateNOCICACValueCommandParameterInfo =
        new CommandParameterInfo("ICACValue", Optional.class, byte[].class);
    operationalCredentialsupdateNOCCommandParams.put(
        "ICACValue", operationalCredentialsupdateNOCICACValueCommandParameterInfo);

    InteractionInfo operationalCredentialsupdateNOCInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .updateNOC(
                      (ChipClusters.OperationalCredentialsCluster.NOCResponseCallback) callback,
                      (byte[]) commandArguments.get("NOCValue"),
                      (Optional<byte[]>) commandArguments.get("ICACValue"));
            },
            () -> new DelegatedOperationalCredentialsClusterNOCResponseCallback(),
            operationalCredentialsupdateNOCCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "updateNOC", operationalCredentialsupdateNOCInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsupdateFabricLabelCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo operationalCredentialsupdateFabricLabellabelCommandParameterInfo =
        new CommandParameterInfo("label", String.class, String.class);
    operationalCredentialsupdateFabricLabelCommandParams.put(
        "label", operationalCredentialsupdateFabricLabellabelCommandParameterInfo);

    InteractionInfo operationalCredentialsupdateFabricLabelInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .updateFabricLabel(
                      (ChipClusters.OperationalCredentialsCluster.NOCResponseCallback) callback,
                      (String) commandArguments.get("label"));
            },
            () -> new DelegatedOperationalCredentialsClusterNOCResponseCallback(),
            operationalCredentialsupdateFabricLabelCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "updateFabricLabel", operationalCredentialsupdateFabricLabelInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsremoveFabricCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo operationalCredentialsremoveFabricfabricIndexCommandParameterInfo =
        new CommandParameterInfo("fabricIndex", Integer.class, Integer.class);
    operationalCredentialsremoveFabricCommandParams.put(
        "fabricIndex", operationalCredentialsremoveFabricfabricIndexCommandParameterInfo);

    InteractionInfo operationalCredentialsremoveFabricInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .removeFabric(
                      (ChipClusters.OperationalCredentialsCluster.NOCResponseCallback) callback,
                      (Integer) commandArguments.get("fabricIndex"));
            },
            () -> new DelegatedOperationalCredentialsClusterNOCResponseCallback(),
            operationalCredentialsremoveFabricCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "removeFabric", operationalCredentialsremoveFabricInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsaddTrustedRootCertificateCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        operationalCredentialsaddTrustedRootCertificaterootCACertificateCommandParameterInfo =
            new CommandParameterInfo("rootCACertificate", byte[].class, byte[].class);
    operationalCredentialsaddTrustedRootCertificateCommandParams.put(
        "rootCACertificate",
        operationalCredentialsaddTrustedRootCertificaterootCACertificateCommandParameterInfo);

    InteractionInfo operationalCredentialsaddTrustedRootCertificateInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .addTrustedRootCertificate(
                      (DefaultClusterCallback) callback,
                      (byte[]) commandArguments.get("rootCACertificate"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            operationalCredentialsaddTrustedRootCertificateCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "addTrustedRootCertificate",
        operationalCredentialsaddTrustedRootCertificateInteractionInfo);
    commandMap.put("operationalCredentials", operationalCredentialsClusterInteractionInfoMap);
    Map<String, InteractionInfo> groupKeyManagementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> groupKeyManagementkeySetWriteCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo groupKeyManagementkeySetWriteInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupKeyManagementCluster) cluster)
                  .keySetWrite(
                      (DefaultClusterCallback) callback,
                      (ChipStructs.GroupKeyManagementClusterGroupKeySetStruct)
                          commandArguments.get("groupKeySet"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            groupKeyManagementkeySetWriteCommandParams);
    groupKeyManagementClusterInteractionInfoMap.put(
        "keySetWrite", groupKeyManagementkeySetWriteInteractionInfo);
    Map<String, CommandParameterInfo> groupKeyManagementkeySetReadCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupKeyManagementkeySetReadgroupKeySetIDCommandParameterInfo =
        new CommandParameterInfo("groupKeySetID", Integer.class, Integer.class);
    groupKeyManagementkeySetReadCommandParams.put(
        "groupKeySetID", groupKeyManagementkeySetReadgroupKeySetIDCommandParameterInfo);

    InteractionInfo groupKeyManagementkeySetReadInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupKeyManagementCluster) cluster)
                  .keySetRead(
                      (ChipClusters.GroupKeyManagementCluster.KeySetReadResponseCallback) callback,
                      (Integer) commandArguments.get("groupKeySetID"));
            },
            () -> new DelegatedGroupKeyManagementClusterKeySetReadResponseCallback(),
            groupKeyManagementkeySetReadCommandParams);
    groupKeyManagementClusterInteractionInfoMap.put(
        "keySetRead", groupKeyManagementkeySetReadInteractionInfo);
    Map<String, CommandParameterInfo> groupKeyManagementkeySetRemoveCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupKeyManagementkeySetRemovegroupKeySetIDCommandParameterInfo =
        new CommandParameterInfo("groupKeySetID", Integer.class, Integer.class);
    groupKeyManagementkeySetRemoveCommandParams.put(
        "groupKeySetID", groupKeyManagementkeySetRemovegroupKeySetIDCommandParameterInfo);

    InteractionInfo groupKeyManagementkeySetRemoveInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupKeyManagementCluster) cluster)
                  .keySetRemove(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("groupKeySetID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            groupKeyManagementkeySetRemoveCommandParams);
    groupKeyManagementClusterInteractionInfoMap.put(
        "keySetRemove", groupKeyManagementkeySetRemoveInteractionInfo);
    Map<String, CommandParameterInfo> groupKeyManagementkeySetReadAllIndicesCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupKeyManagementkeySetReadAllIndicesgroupKeySetIDsCommandParameterInfo =
        new CommandParameterInfo("groupKeySetIDs", ArrayList.class, Integer.class);
    groupKeyManagementkeySetReadAllIndicesCommandParams.put(
        "groupKeySetIDs", groupKeyManagementkeySetReadAllIndicesgroupKeySetIDsCommandParameterInfo);

    InteractionInfo groupKeyManagementkeySetReadAllIndicesInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupKeyManagementCluster) cluster)
                  .keySetReadAllIndices(
                      (ChipClusters.GroupKeyManagementCluster.KeySetReadAllIndicesResponseCallback)
                          callback,
                      (ArrayList<Integer>) commandArguments.get("groupKeySetIDs"));
            },
            () -> new DelegatedGroupKeyManagementClusterKeySetReadAllIndicesResponseCallback(),
            groupKeyManagementkeySetReadAllIndicesCommandParams);
    groupKeyManagementClusterInteractionInfoMap.put(
        "keySetReadAllIndices", groupKeyManagementkeySetReadAllIndicesInteractionInfo);
    commandMap.put("groupKeyManagement", groupKeyManagementClusterInteractionInfoMap);
    Map<String, InteractionInfo> fixedLabelClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("fixedLabel", fixedLabelClusterInteractionInfoMap);
    Map<String, InteractionInfo> userLabelClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("userLabel", userLabelClusterInteractionInfoMap);
    Map<String, InteractionInfo> proxyConfigurationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("proxyConfiguration", proxyConfigurationClusterInteractionInfoMap);
    Map<String, InteractionInfo> proxyDiscoveryClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("proxyDiscovery", proxyDiscoveryClusterInteractionInfoMap);
    Map<String, InteractionInfo> proxyValidClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("proxyValid", proxyValidClusterInteractionInfoMap);
    Map<String, InteractionInfo> booleanStateClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("booleanState", booleanStateClusterInteractionInfoMap);
    Map<String, InteractionInfo> icdManagementClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> icdManagementregisterClientCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo icdManagementregisterClientcheckInNodeIDCommandParameterInfo =
        new CommandParameterInfo("checkInNodeID", Long.class, Long.class);
    icdManagementregisterClientCommandParams.put(
        "checkInNodeID", icdManagementregisterClientcheckInNodeIDCommandParameterInfo);

    CommandParameterInfo icdManagementregisterClientmonitoredSubjectCommandParameterInfo =
        new CommandParameterInfo("monitoredSubject", Long.class, Long.class);
    icdManagementregisterClientCommandParams.put(
        "monitoredSubject", icdManagementregisterClientmonitoredSubjectCommandParameterInfo);

    CommandParameterInfo icdManagementregisterClientkeyCommandParameterInfo =
        new CommandParameterInfo("key", byte[].class, byte[].class);
    icdManagementregisterClientCommandParams.put(
        "key", icdManagementregisterClientkeyCommandParameterInfo);

    CommandParameterInfo icdManagementregisterClientverificationKeyCommandParameterInfo =
        new CommandParameterInfo("verificationKey", Optional.class, byte[].class);
    icdManagementregisterClientCommandParams.put(
        "verificationKey", icdManagementregisterClientverificationKeyCommandParameterInfo);

    InteractionInfo icdManagementregisterClientInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.IcdManagementCluster) cluster)
                  .registerClient(
                      (ChipClusters.IcdManagementCluster.RegisterClientResponseCallback) callback,
                      (Long) commandArguments.get("checkInNodeID"),
                      (Long) commandArguments.get("monitoredSubject"),
                      (byte[]) commandArguments.get("key"),
                      (Optional<byte[]>) commandArguments.get("verificationKey"));
            },
            () -> new DelegatedIcdManagementClusterRegisterClientResponseCallback(),
            icdManagementregisterClientCommandParams);
    icdManagementClusterInteractionInfoMap.put(
        "registerClient", icdManagementregisterClientInteractionInfo);
    Map<String, CommandParameterInfo> icdManagementunregisterClientCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo icdManagementunregisterClientcheckInNodeIDCommandParameterInfo =
        new CommandParameterInfo("checkInNodeID", Long.class, Long.class);
    icdManagementunregisterClientCommandParams.put(
        "checkInNodeID", icdManagementunregisterClientcheckInNodeIDCommandParameterInfo);

    CommandParameterInfo icdManagementunregisterClientkeyCommandParameterInfo =
        new CommandParameterInfo("key", Optional.class, byte[].class);
    icdManagementunregisterClientCommandParams.put(
        "key", icdManagementunregisterClientkeyCommandParameterInfo);

    InteractionInfo icdManagementunregisterClientInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.IcdManagementCluster) cluster)
                  .unregisterClient(
                      (DefaultClusterCallback) callback,
                      (Long) commandArguments.get("checkInNodeID"),
                      (Optional<byte[]>) commandArguments.get("key"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            icdManagementunregisterClientCommandParams);
    icdManagementClusterInteractionInfoMap.put(
        "unregisterClient", icdManagementunregisterClientInteractionInfo);
    Map<String, CommandParameterInfo> icdManagementstayActiveRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo icdManagementstayActiveRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.IcdManagementCluster) cluster)
                  .stayActiveRequest((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            icdManagementstayActiveRequestCommandParams);
    icdManagementClusterInteractionInfoMap.put(
        "stayActiveRequest", icdManagementstayActiveRequestInteractionInfo);
    commandMap.put("icdManagement", icdManagementClusterInteractionInfoMap);
    Map<String, InteractionInfo> modeSelectClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> modeSelectchangeToModeCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo modeSelectchangeToModenewModeCommandParameterInfo =
        new CommandParameterInfo("newMode", Integer.class, Integer.class);
    modeSelectchangeToModeCommandParams.put(
        "newMode", modeSelectchangeToModenewModeCommandParameterInfo);

    InteractionInfo modeSelectchangeToModeInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ModeSelectCluster) cluster)
                  .changeToMode(
                      (DefaultClusterCallback) callback, (Integer) commandArguments.get("newMode"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            modeSelectchangeToModeCommandParams);
    modeSelectClusterInteractionInfoMap.put("changeToMode", modeSelectchangeToModeInteractionInfo);
    commandMap.put("modeSelect", modeSelectClusterInteractionInfoMap);
    Map<String, InteractionInfo> temperatureControlClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("temperatureControl", temperatureControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> refrigeratorAlarmClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> refrigeratorAlarmresetCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo refrigeratorAlarmresetalarmsCommandParameterInfo =
        new CommandParameterInfo("alarms", Long.class, Long.class);
    refrigeratorAlarmresetCommandParams.put(
        "alarms", refrigeratorAlarmresetalarmsCommandParameterInfo);

    CommandParameterInfo refrigeratorAlarmresetmaskCommandParameterInfo =
        new CommandParameterInfo("mask", Optional.class, Long.class);
    refrigeratorAlarmresetCommandParams.put("mask", refrigeratorAlarmresetmaskCommandParameterInfo);

    InteractionInfo refrigeratorAlarmresetInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.RefrigeratorAlarmCluster) cluster)
                  .reset(
                      (DefaultClusterCallback) callback,
                      (Long) commandArguments.get("alarms"),
                      (Optional<Long>) commandArguments.get("mask"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            refrigeratorAlarmresetCommandParams);
    refrigeratorAlarmClusterInteractionInfoMap.put("reset", refrigeratorAlarmresetInteractionInfo);
    commandMap.put("refrigeratorAlarm", refrigeratorAlarmClusterInteractionInfoMap);
    Map<String, InteractionInfo> airQualityClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("airQuality", airQualityClusterInteractionInfoMap);
    Map<String, InteractionInfo> smokeCoAlarmClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> smokeCoAlarmselfTestRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo smokeCoAlarmselfTestRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.SmokeCoAlarmCluster) cluster)
                  .selfTestRequest((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            smokeCoAlarmselfTestRequestCommandParams);
    smokeCoAlarmClusterInteractionInfoMap.put(
        "selfTestRequest", smokeCoAlarmselfTestRequestInteractionInfo);
    commandMap.put("smokeCoAlarm", smokeCoAlarmClusterInteractionInfoMap);
    Map<String, InteractionInfo> hepaFilterMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("hepaFilterMonitoring", hepaFilterMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> activatedCarbonFilterMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put(
        "activatedCarbonFilterMonitoring",
        activatedCarbonFilterMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> ceramicFilterMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("ceramicFilterMonitoring", ceramicFilterMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> electrostaticFilterMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put(
        "electrostaticFilterMonitoring", electrostaticFilterMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> uvFilterMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("uvFilterMonitoring", uvFilterMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> ionizingFilterMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("ionizingFilterMonitoring", ionizingFilterMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> zeoliteFilterMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("zeoliteFilterMonitoring", zeoliteFilterMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> ozoneFilterMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("ozoneFilterMonitoring", ozoneFilterMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> waterTankMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("waterTankMonitoring", waterTankMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> fuelTankMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("fuelTankMonitoring", fuelTankMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> inkCartridgeMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("inkCartridgeMonitoring", inkCartridgeMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> tonerCartridgeMonitoringClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("tonerCartridgeMonitoring", tonerCartridgeMonitoringClusterInteractionInfoMap);
    Map<String, InteractionInfo> doorLockClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> doorLocklockDoorCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocklockDoorPINCodeCommandParameterInfo =
        new CommandParameterInfo("PINCode", Optional.class, byte[].class);
    doorLocklockDoorCommandParams.put("PINCode", doorLocklockDoorPINCodeCommandParameterInfo);

    InteractionInfo doorLocklockDoorInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .lockDoor(
                      (DefaultClusterCallback) callback,
                      (Optional<byte[]>) commandArguments.get("PINCode"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLocklockDoorCommandParams);
    doorLockClusterInteractionInfoMap.put("lockDoor", doorLocklockDoorInteractionInfo);
    Map<String, CommandParameterInfo> doorLockunlockDoorCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockunlockDoorPINCodeCommandParameterInfo =
        new CommandParameterInfo("PINCode", Optional.class, byte[].class);
    doorLockunlockDoorCommandParams.put("PINCode", doorLockunlockDoorPINCodeCommandParameterInfo);

    InteractionInfo doorLockunlockDoorInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .unlockDoor(
                      (DefaultClusterCallback) callback,
                      (Optional<byte[]>) commandArguments.get("PINCode"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockunlockDoorCommandParams);
    doorLockClusterInteractionInfoMap.put("unlockDoor", doorLockunlockDoorInteractionInfo);
    Map<String, CommandParameterInfo> doorLockunlockWithTimeoutCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockunlockWithTimeouttimeoutCommandParameterInfo =
        new CommandParameterInfo("timeout", Integer.class, Integer.class);
    doorLockunlockWithTimeoutCommandParams.put(
        "timeout", doorLockunlockWithTimeouttimeoutCommandParameterInfo);

    CommandParameterInfo doorLockunlockWithTimeoutPINCodeCommandParameterInfo =
        new CommandParameterInfo("PINCode", Optional.class, byte[].class);
    doorLockunlockWithTimeoutCommandParams.put(
        "PINCode", doorLockunlockWithTimeoutPINCodeCommandParameterInfo);

    InteractionInfo doorLockunlockWithTimeoutInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .unlockWithTimeout(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("timeout"),
                      (Optional<byte[]>) commandArguments.get("PINCode"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockunlockWithTimeoutCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "unlockWithTimeout", doorLockunlockWithTimeoutInteractionInfo);
    Map<String, CommandParameterInfo> doorLocksetWeekDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocksetWeekDayScheduleweekDayIndexCommandParameterInfo =
        new CommandParameterInfo("weekDayIndex", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "weekDayIndex", doorLocksetWeekDayScheduleweekDayIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "userIndex", doorLocksetWeekDayScheduleuserIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDayScheduledaysMaskCommandParameterInfo =
        new CommandParameterInfo("daysMask", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "daysMask", doorLocksetWeekDayScheduledaysMaskCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDaySchedulestartHourCommandParameterInfo =
        new CommandParameterInfo("startHour", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "startHour", doorLocksetWeekDaySchedulestartHourCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDaySchedulestartMinuteCommandParameterInfo =
        new CommandParameterInfo("startMinute", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "startMinute", doorLocksetWeekDaySchedulestartMinuteCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDayScheduleendHourCommandParameterInfo =
        new CommandParameterInfo("endHour", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "endHour", doorLocksetWeekDayScheduleendHourCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDayScheduleendMinuteCommandParameterInfo =
        new CommandParameterInfo("endMinute", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "endMinute", doorLocksetWeekDayScheduleendMinuteCommandParameterInfo);

    InteractionInfo doorLocksetWeekDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .setWeekDaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("weekDayIndex"),
                      (Integer) commandArguments.get("userIndex"),
                      (Integer) commandArguments.get("daysMask"),
                      (Integer) commandArguments.get("startHour"),
                      (Integer) commandArguments.get("startMinute"),
                      (Integer) commandArguments.get("endHour"),
                      (Integer) commandArguments.get("endMinute"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLocksetWeekDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "setWeekDaySchedule", doorLocksetWeekDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockgetWeekDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockgetWeekDayScheduleweekDayIndexCommandParameterInfo =
        new CommandParameterInfo("weekDayIndex", Integer.class, Integer.class);
    doorLockgetWeekDayScheduleCommandParams.put(
        "weekDayIndex", doorLockgetWeekDayScheduleweekDayIndexCommandParameterInfo);

    CommandParameterInfo doorLockgetWeekDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockgetWeekDayScheduleCommandParams.put(
        "userIndex", doorLockgetWeekDayScheduleuserIndexCommandParameterInfo);

    InteractionInfo doorLockgetWeekDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .getWeekDaySchedule(
                      (ChipClusters.DoorLockCluster.GetWeekDayScheduleResponseCallback) callback,
                      (Integer) commandArguments.get("weekDayIndex"),
                      (Integer) commandArguments.get("userIndex"));
            },
            () -> new DelegatedDoorLockClusterGetWeekDayScheduleResponseCallback(),
            doorLockgetWeekDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "getWeekDaySchedule", doorLockgetWeekDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockclearWeekDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockclearWeekDayScheduleweekDayIndexCommandParameterInfo =
        new CommandParameterInfo("weekDayIndex", Integer.class, Integer.class);
    doorLockclearWeekDayScheduleCommandParams.put(
        "weekDayIndex", doorLockclearWeekDayScheduleweekDayIndexCommandParameterInfo);

    CommandParameterInfo doorLockclearWeekDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockclearWeekDayScheduleCommandParams.put(
        "userIndex", doorLockclearWeekDayScheduleuserIndexCommandParameterInfo);

    InteractionInfo doorLockclearWeekDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .clearWeekDaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("weekDayIndex"),
                      (Integer) commandArguments.get("userIndex"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockclearWeekDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "clearWeekDaySchedule", doorLockclearWeekDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLocksetYearDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocksetYearDayScheduleyearDayIndexCommandParameterInfo =
        new CommandParameterInfo("yearDayIndex", Integer.class, Integer.class);
    doorLocksetYearDayScheduleCommandParams.put(
        "yearDayIndex", doorLocksetYearDayScheduleyearDayIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetYearDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLocksetYearDayScheduleCommandParams.put(
        "userIndex", doorLocksetYearDayScheduleuserIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetYearDaySchedulelocalStartTimeCommandParameterInfo =
        new CommandParameterInfo("localStartTime", Long.class, Long.class);
    doorLocksetYearDayScheduleCommandParams.put(
        "localStartTime", doorLocksetYearDaySchedulelocalStartTimeCommandParameterInfo);

    CommandParameterInfo doorLocksetYearDaySchedulelocalEndTimeCommandParameterInfo =
        new CommandParameterInfo("localEndTime", Long.class, Long.class);
    doorLocksetYearDayScheduleCommandParams.put(
        "localEndTime", doorLocksetYearDaySchedulelocalEndTimeCommandParameterInfo);

    InteractionInfo doorLocksetYearDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .setYearDaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("yearDayIndex"),
                      (Integer) commandArguments.get("userIndex"),
                      (Long) commandArguments.get("localStartTime"),
                      (Long) commandArguments.get("localEndTime"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLocksetYearDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "setYearDaySchedule", doorLocksetYearDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockgetYearDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockgetYearDayScheduleyearDayIndexCommandParameterInfo =
        new CommandParameterInfo("yearDayIndex", Integer.class, Integer.class);
    doorLockgetYearDayScheduleCommandParams.put(
        "yearDayIndex", doorLockgetYearDayScheduleyearDayIndexCommandParameterInfo);

    CommandParameterInfo doorLockgetYearDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockgetYearDayScheduleCommandParams.put(
        "userIndex", doorLockgetYearDayScheduleuserIndexCommandParameterInfo);

    InteractionInfo doorLockgetYearDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .getYearDaySchedule(
                      (ChipClusters.DoorLockCluster.GetYearDayScheduleResponseCallback) callback,
                      (Integer) commandArguments.get("yearDayIndex"),
                      (Integer) commandArguments.get("userIndex"));
            },
            () -> new DelegatedDoorLockClusterGetYearDayScheduleResponseCallback(),
            doorLockgetYearDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "getYearDaySchedule", doorLockgetYearDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockclearYearDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockclearYearDayScheduleyearDayIndexCommandParameterInfo =
        new CommandParameterInfo("yearDayIndex", Integer.class, Integer.class);
    doorLockclearYearDayScheduleCommandParams.put(
        "yearDayIndex", doorLockclearYearDayScheduleyearDayIndexCommandParameterInfo);

    CommandParameterInfo doorLockclearYearDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockclearYearDayScheduleCommandParams.put(
        "userIndex", doorLockclearYearDayScheduleuserIndexCommandParameterInfo);

    InteractionInfo doorLockclearYearDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .clearYearDaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("yearDayIndex"),
                      (Integer) commandArguments.get("userIndex"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockclearYearDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "clearYearDaySchedule", doorLockclearYearDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLocksetHolidayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocksetHolidayScheduleholidayIndexCommandParameterInfo =
        new CommandParameterInfo("holidayIndex", Integer.class, Integer.class);
    doorLocksetHolidayScheduleCommandParams.put(
        "holidayIndex", doorLocksetHolidayScheduleholidayIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetHolidaySchedulelocalStartTimeCommandParameterInfo =
        new CommandParameterInfo("localStartTime", Long.class, Long.class);
    doorLocksetHolidayScheduleCommandParams.put(
        "localStartTime", doorLocksetHolidaySchedulelocalStartTimeCommandParameterInfo);

    CommandParameterInfo doorLocksetHolidaySchedulelocalEndTimeCommandParameterInfo =
        new CommandParameterInfo("localEndTime", Long.class, Long.class);
    doorLocksetHolidayScheduleCommandParams.put(
        "localEndTime", doorLocksetHolidaySchedulelocalEndTimeCommandParameterInfo);

    CommandParameterInfo doorLocksetHolidayScheduleoperatingModeCommandParameterInfo =
        new CommandParameterInfo("operatingMode", Integer.class, Integer.class);
    doorLocksetHolidayScheduleCommandParams.put(
        "operatingMode", doorLocksetHolidayScheduleoperatingModeCommandParameterInfo);

    InteractionInfo doorLocksetHolidayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .setHolidaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("holidayIndex"),
                      (Long) commandArguments.get("localStartTime"),
                      (Long) commandArguments.get("localEndTime"),
                      (Integer) commandArguments.get("operatingMode"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLocksetHolidayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "setHolidaySchedule", doorLocksetHolidayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockgetHolidayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockgetHolidayScheduleholidayIndexCommandParameterInfo =
        new CommandParameterInfo("holidayIndex", Integer.class, Integer.class);
    doorLockgetHolidayScheduleCommandParams.put(
        "holidayIndex", doorLockgetHolidayScheduleholidayIndexCommandParameterInfo);

    InteractionInfo doorLockgetHolidayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .getHolidaySchedule(
                      (ChipClusters.DoorLockCluster.GetHolidayScheduleResponseCallback) callback,
                      (Integer) commandArguments.get("holidayIndex"));
            },
            () -> new DelegatedDoorLockClusterGetHolidayScheduleResponseCallback(),
            doorLockgetHolidayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "getHolidaySchedule", doorLockgetHolidayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockclearHolidayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockclearHolidayScheduleholidayIndexCommandParameterInfo =
        new CommandParameterInfo("holidayIndex", Integer.class, Integer.class);
    doorLockclearHolidayScheduleCommandParams.put(
        "holidayIndex", doorLockclearHolidayScheduleholidayIndexCommandParameterInfo);

    InteractionInfo doorLockclearHolidayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .clearHolidaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("holidayIndex"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockclearHolidayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "clearHolidaySchedule", doorLockclearHolidayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLocksetUserCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocksetUseroperationTypeCommandParameterInfo =
        new CommandParameterInfo("operationType", Integer.class, Integer.class);
    doorLocksetUserCommandParams.put(
        "operationType", doorLocksetUseroperationTypeCommandParameterInfo);

    CommandParameterInfo doorLocksetUseruserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLocksetUserCommandParams.put("userIndex", doorLocksetUseruserIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetUseruserNameCommandParameterInfo =
        new CommandParameterInfo("userName", String.class, String.class);
    doorLocksetUserCommandParams.put("userName", doorLocksetUseruserNameCommandParameterInfo);

    CommandParameterInfo doorLocksetUseruserUniqueIDCommandParameterInfo =
        new CommandParameterInfo("userUniqueID", Long.class, Long.class);
    doorLocksetUserCommandParams.put(
        "userUniqueID", doorLocksetUseruserUniqueIDCommandParameterInfo);

    CommandParameterInfo doorLocksetUseruserStatusCommandParameterInfo =
        new CommandParameterInfo("userStatus", Integer.class, Integer.class);
    doorLocksetUserCommandParams.put("userStatus", doorLocksetUseruserStatusCommandParameterInfo);

    CommandParameterInfo doorLocksetUseruserTypeCommandParameterInfo =
        new CommandParameterInfo("userType", Integer.class, Integer.class);
    doorLocksetUserCommandParams.put("userType", doorLocksetUseruserTypeCommandParameterInfo);

    CommandParameterInfo doorLocksetUsercredentialRuleCommandParameterInfo =
        new CommandParameterInfo("credentialRule", Integer.class, Integer.class);
    doorLocksetUserCommandParams.put(
        "credentialRule", doorLocksetUsercredentialRuleCommandParameterInfo);

    InteractionInfo doorLocksetUserInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .setUser(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("operationType"),
                      (Integer) commandArguments.get("userIndex"),
                      (String) commandArguments.get("userName"),
                      (Long) commandArguments.get("userUniqueID"),
                      (Integer) commandArguments.get("userStatus"),
                      (Integer) commandArguments.get("userType"),
                      (Integer) commandArguments.get("credentialRule"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLocksetUserCommandParams);
    doorLockClusterInteractionInfoMap.put("setUser", doorLocksetUserInteractionInfo);
    Map<String, CommandParameterInfo> doorLockgetUserCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockgetUseruserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockgetUserCommandParams.put("userIndex", doorLockgetUseruserIndexCommandParameterInfo);

    InteractionInfo doorLockgetUserInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .getUser(
                      (ChipClusters.DoorLockCluster.GetUserResponseCallback) callback,
                      (Integer) commandArguments.get("userIndex"));
            },
            () -> new DelegatedDoorLockClusterGetUserResponseCallback(),
            doorLockgetUserCommandParams);
    doorLockClusterInteractionInfoMap.put("getUser", doorLockgetUserInteractionInfo);
    Map<String, CommandParameterInfo> doorLockclearUserCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockclearUseruserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockclearUserCommandParams.put("userIndex", doorLockclearUseruserIndexCommandParameterInfo);

    InteractionInfo doorLockclearUserInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .clearUser(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("userIndex"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockclearUserCommandParams);
    doorLockClusterInteractionInfoMap.put("clearUser", doorLockclearUserInteractionInfo);
    Map<String, CommandParameterInfo> doorLocksetCredentialCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocksetCredentialoperationTypeCommandParameterInfo =
        new CommandParameterInfo("operationType", Integer.class, Integer.class);
    doorLocksetCredentialCommandParams.put(
        "operationType", doorLocksetCredentialoperationTypeCommandParameterInfo);

    CommandParameterInfo doorLocksetCredentialcredentialDataCommandParameterInfo =
        new CommandParameterInfo("credentialData", byte[].class, byte[].class);
    doorLocksetCredentialCommandParams.put(
        "credentialData", doorLocksetCredentialcredentialDataCommandParameterInfo);

    CommandParameterInfo doorLocksetCredentialuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLocksetCredentialCommandParams.put(
        "userIndex", doorLocksetCredentialuserIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetCredentialuserStatusCommandParameterInfo =
        new CommandParameterInfo("userStatus", Integer.class, Integer.class);
    doorLocksetCredentialCommandParams.put(
        "userStatus", doorLocksetCredentialuserStatusCommandParameterInfo);

    CommandParameterInfo doorLocksetCredentialuserTypeCommandParameterInfo =
        new CommandParameterInfo("userType", Integer.class, Integer.class);
    doorLocksetCredentialCommandParams.put(
        "userType", doorLocksetCredentialuserTypeCommandParameterInfo);

    InteractionInfo doorLocksetCredentialInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .setCredential(
                      (ChipClusters.DoorLockCluster.SetCredentialResponseCallback) callback,
                      (Integer) commandArguments.get("operationType"),
                      (ChipStructs.DoorLockClusterCredentialStruct)
                          commandArguments.get("credential"),
                      (byte[]) commandArguments.get("credentialData"),
                      (Integer) commandArguments.get("userIndex"),
                      (Integer) commandArguments.get("userStatus"),
                      (Integer) commandArguments.get("userType"),
                      10000);
            },
            () -> new DelegatedDoorLockClusterSetCredentialResponseCallback(),
            doorLocksetCredentialCommandParams);
    doorLockClusterInteractionInfoMap.put("setCredential", doorLocksetCredentialInteractionInfo);
    Map<String, CommandParameterInfo> doorLockgetCredentialStatusCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo doorLockgetCredentialStatusInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .getCredentialStatus(
                      (ChipClusters.DoorLockCluster.GetCredentialStatusResponseCallback) callback,
                      (ChipStructs.DoorLockClusterCredentialStruct)
                          commandArguments.get("credential"));
            },
            () -> new DelegatedDoorLockClusterGetCredentialStatusResponseCallback(),
            doorLockgetCredentialStatusCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "getCredentialStatus", doorLockgetCredentialStatusInteractionInfo);
    Map<String, CommandParameterInfo> doorLockclearCredentialCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo doorLockclearCredentialInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .clearCredential(
                      (DefaultClusterCallback) callback,
                      (ChipStructs.DoorLockClusterCredentialStruct)
                          commandArguments.get("credential"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockclearCredentialCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "clearCredential", doorLockclearCredentialInteractionInfo);
    commandMap.put("doorLock", doorLockClusterInteractionInfoMap);
    Map<String, InteractionInfo> windowCoveringClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> windowCoveringupOrOpenCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo windowCoveringupOrOpenInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .upOrOpen((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringupOrOpenCommandParams);
    windowCoveringClusterInteractionInfoMap.put("upOrOpen", windowCoveringupOrOpenInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringdownOrCloseCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo windowCoveringdownOrCloseInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .downOrClose((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringdownOrCloseCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "downOrClose", windowCoveringdownOrCloseInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringstopMotionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo windowCoveringstopMotionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .stopMotion((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringstopMotionCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "stopMotion", windowCoveringstopMotionInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringgoToLiftValueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo windowCoveringgoToLiftValueliftValueCommandParameterInfo =
        new CommandParameterInfo("liftValue", Integer.class, Integer.class);
    windowCoveringgoToLiftValueCommandParams.put(
        "liftValue", windowCoveringgoToLiftValueliftValueCommandParameterInfo);

    InteractionInfo windowCoveringgoToLiftValueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .goToLiftValue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("liftValue"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringgoToLiftValueCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "goToLiftValue", windowCoveringgoToLiftValueInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringgoToLiftPercentageCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        windowCoveringgoToLiftPercentageliftPercent100thsValueCommandParameterInfo =
            new CommandParameterInfo("liftPercent100thsValue", Integer.class, Integer.class);
    windowCoveringgoToLiftPercentageCommandParams.put(
        "liftPercent100thsValue",
        windowCoveringgoToLiftPercentageliftPercent100thsValueCommandParameterInfo);

    InteractionInfo windowCoveringgoToLiftPercentageInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .goToLiftPercentage(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("liftPercent100thsValue"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringgoToLiftPercentageCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "goToLiftPercentage", windowCoveringgoToLiftPercentageInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringgoToTiltValueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo windowCoveringgoToTiltValuetiltValueCommandParameterInfo =
        new CommandParameterInfo("tiltValue", Integer.class, Integer.class);
    windowCoveringgoToTiltValueCommandParams.put(
        "tiltValue", windowCoveringgoToTiltValuetiltValueCommandParameterInfo);

    InteractionInfo windowCoveringgoToTiltValueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .goToTiltValue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("tiltValue"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringgoToTiltValueCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "goToTiltValue", windowCoveringgoToTiltValueInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringgoToTiltPercentageCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        windowCoveringgoToTiltPercentagetiltPercent100thsValueCommandParameterInfo =
            new CommandParameterInfo("tiltPercent100thsValue", Integer.class, Integer.class);
    windowCoveringgoToTiltPercentageCommandParams.put(
        "tiltPercent100thsValue",
        windowCoveringgoToTiltPercentagetiltPercent100thsValueCommandParameterInfo);

    InteractionInfo windowCoveringgoToTiltPercentageInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .goToTiltPercentage(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("tiltPercent100thsValue"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringgoToTiltPercentageCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "goToTiltPercentage", windowCoveringgoToTiltPercentageInteractionInfo);
    commandMap.put("windowCovering", windowCoveringClusterInteractionInfoMap);
    Map<String, InteractionInfo> barrierControlClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> barrierControlbarrierControlGoToPercentCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo barrierControlbarrierControlGoToPercentpercentOpenCommandParameterInfo =
        new CommandParameterInfo("percentOpen", Integer.class, Integer.class);
    barrierControlbarrierControlGoToPercentCommandParams.put(
        "percentOpen", barrierControlbarrierControlGoToPercentpercentOpenCommandParameterInfo);

    InteractionInfo barrierControlbarrierControlGoToPercentInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BarrierControlCluster) cluster)
                  .barrierControlGoToPercent(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("percentOpen"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            barrierControlbarrierControlGoToPercentCommandParams);
    barrierControlClusterInteractionInfoMap.put(
        "barrierControlGoToPercent", barrierControlbarrierControlGoToPercentInteractionInfo);
    Map<String, CommandParameterInfo> barrierControlbarrierControlStopCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo barrierControlbarrierControlStopInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BarrierControlCluster) cluster)
                  .barrierControlStop((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            barrierControlbarrierControlStopCommandParams);
    barrierControlClusterInteractionInfoMap.put(
        "barrierControlStop", barrierControlbarrierControlStopInteractionInfo);
    commandMap.put("barrierControl", barrierControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> pumpConfigurationAndControlClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put(
        "pumpConfigurationAndControl", pumpConfigurationAndControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> thermostatClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> thermostatsetpointRaiseLowerCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo thermostatsetpointRaiseLowermodeCommandParameterInfo =
        new CommandParameterInfo("mode", Integer.class, Integer.class);
    thermostatsetpointRaiseLowerCommandParams.put(
        "mode", thermostatsetpointRaiseLowermodeCommandParameterInfo);

    CommandParameterInfo thermostatsetpointRaiseLoweramountCommandParameterInfo =
        new CommandParameterInfo("amount", Integer.class, Integer.class);
    thermostatsetpointRaiseLowerCommandParams.put(
        "amount", thermostatsetpointRaiseLoweramountCommandParameterInfo);

    InteractionInfo thermostatsetpointRaiseLowerInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ThermostatCluster) cluster)
                  .setpointRaiseLower(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("mode"),
                      (Integer) commandArguments.get("amount"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            thermostatsetpointRaiseLowerCommandParams);
    thermostatClusterInteractionInfoMap.put(
        "setpointRaiseLower", thermostatsetpointRaiseLowerInteractionInfo);
    Map<String, CommandParameterInfo> thermostatsetWeeklyScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        thermostatsetWeeklySchedulenumberOfTransitionsForSequenceCommandParameterInfo =
            new CommandParameterInfo(
                "numberOfTransitionsForSequence", Integer.class, Integer.class);
    thermostatsetWeeklyScheduleCommandParams.put(
        "numberOfTransitionsForSequence",
        thermostatsetWeeklySchedulenumberOfTransitionsForSequenceCommandParameterInfo);

    CommandParameterInfo thermostatsetWeeklyScheduledayOfWeekForSequenceCommandParameterInfo =
        new CommandParameterInfo("dayOfWeekForSequence", Integer.class, Integer.class);
    thermostatsetWeeklyScheduleCommandParams.put(
        "dayOfWeekForSequence",
        thermostatsetWeeklyScheduledayOfWeekForSequenceCommandParameterInfo);

    CommandParameterInfo thermostatsetWeeklySchedulemodeForSequenceCommandParameterInfo =
        new CommandParameterInfo("modeForSequence", Integer.class, Integer.class);
    thermostatsetWeeklyScheduleCommandParams.put(
        "modeForSequence", thermostatsetWeeklySchedulemodeForSequenceCommandParameterInfo);

    InteractionInfo thermostatsetWeeklyScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ThermostatCluster) cluster)
                  .setWeeklySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("numberOfTransitionsForSequence"),
                      (Integer) commandArguments.get("dayOfWeekForSequence"),
                      (Integer) commandArguments.get("modeForSequence"),
                      (ArrayList<ChipStructs.ThermostatClusterThermostatScheduleTransition>)
                          commandArguments.get("transitions"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            thermostatsetWeeklyScheduleCommandParams);
    thermostatClusterInteractionInfoMap.put(
        "setWeeklySchedule", thermostatsetWeeklyScheduleInteractionInfo);
    Map<String, CommandParameterInfo> thermostatgetWeeklyScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo thermostatgetWeeklyScheduledaysToReturnCommandParameterInfo =
        new CommandParameterInfo("daysToReturn", Integer.class, Integer.class);
    thermostatgetWeeklyScheduleCommandParams.put(
        "daysToReturn", thermostatgetWeeklyScheduledaysToReturnCommandParameterInfo);

    CommandParameterInfo thermostatgetWeeklySchedulemodeToReturnCommandParameterInfo =
        new CommandParameterInfo("modeToReturn", Integer.class, Integer.class);
    thermostatgetWeeklyScheduleCommandParams.put(
        "modeToReturn", thermostatgetWeeklySchedulemodeToReturnCommandParameterInfo);

    InteractionInfo thermostatgetWeeklyScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ThermostatCluster) cluster)
                  .getWeeklySchedule(
                      (ChipClusters.ThermostatCluster.GetWeeklyScheduleResponseCallback) callback,
                      (Integer) commandArguments.get("daysToReturn"),
                      (Integer) commandArguments.get("modeToReturn"));
            },
            () -> new DelegatedThermostatClusterGetWeeklyScheduleResponseCallback(),
            thermostatgetWeeklyScheduleCommandParams);
    thermostatClusterInteractionInfoMap.put(
        "getWeeklySchedule", thermostatgetWeeklyScheduleInteractionInfo);
    Map<String, CommandParameterInfo> thermostatclearWeeklyScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo thermostatclearWeeklyScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ThermostatCluster) cluster)
                  .clearWeeklySchedule((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            thermostatclearWeeklyScheduleCommandParams);
    thermostatClusterInteractionInfoMap.put(
        "clearWeeklySchedule", thermostatclearWeeklyScheduleInteractionInfo);
    commandMap.put("thermostat", thermostatClusterInteractionInfoMap);
    Map<String, InteractionInfo> fanControlClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("fanControl", fanControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> thermostatUserInterfaceConfigurationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put(
        "thermostatUserInterfaceConfiguration",
        thermostatUserInterfaceConfigurationClusterInteractionInfoMap);
    Map<String, InteractionInfo> colorControlClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> colorControlmoveToHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveToHuehueCommandParameterInfo =
        new CommandParameterInfo("hue", Integer.class, Integer.class);
    colorControlmoveToHueCommandParams.put("hue", colorControlmoveToHuehueCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHuedirectionCommandParameterInfo =
        new CommandParameterInfo("direction", Integer.class, Integer.class);
    colorControlmoveToHueCommandParams.put(
        "direction", colorControlmoveToHuedirectionCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHuetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlmoveToHueCommandParams.put(
        "transitionTime", colorControlmoveToHuetransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveToHueCommandParams.put(
        "optionsMask", colorControlmoveToHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveToHueCommandParams.put(
        "optionsOverride", colorControlmoveToHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveToHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveToHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("hue"),
                      (Integer) commandArguments.get("direction"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveToHueCommandParams);
    colorControlClusterInteractionInfoMap.put("moveToHue", colorControlmoveToHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveHuemoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    colorControlmoveHueCommandParams.put(
        "moveMode", colorControlmoveHuemoveModeCommandParameterInfo);

    CommandParameterInfo colorControlmoveHuerateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    colorControlmoveHueCommandParams.put("rate", colorControlmoveHuerateCommandParameterInfo);

    CommandParameterInfo colorControlmoveHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveHueCommandParams.put(
        "optionsMask", colorControlmoveHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveHueCommandParams.put(
        "optionsOverride", colorControlmoveHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveHueCommandParams);
    colorControlClusterInteractionInfoMap.put("moveHue", colorControlmoveHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlstepHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlstepHuestepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    colorControlstepHueCommandParams.put(
        "stepMode", colorControlstepHuestepModeCommandParameterInfo);

    CommandParameterInfo colorControlstepHuestepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    colorControlstepHueCommandParams.put(
        "stepSize", colorControlstepHuestepSizeCommandParameterInfo);

    CommandParameterInfo colorControlstepHuetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlstepHueCommandParams.put(
        "transitionTime", colorControlstepHuetransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlstepHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlstepHueCommandParams.put(
        "optionsMask", colorControlstepHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlstepHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlstepHueCommandParams.put(
        "optionsOverride", colorControlstepHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlstepHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .stepHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlstepHueCommandParams);
    colorControlClusterInteractionInfoMap.put("stepHue", colorControlstepHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveToSaturationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveToSaturationsaturationCommandParameterInfo =
        new CommandParameterInfo("saturation", Integer.class, Integer.class);
    colorControlmoveToSaturationCommandParams.put(
        "saturation", colorControlmoveToSaturationsaturationCommandParameterInfo);

    CommandParameterInfo colorControlmoveToSaturationtransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlmoveToSaturationCommandParams.put(
        "transitionTime", colorControlmoveToSaturationtransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlmoveToSaturationoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveToSaturationCommandParams.put(
        "optionsMask", colorControlmoveToSaturationoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveToSaturationoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveToSaturationCommandParams.put(
        "optionsOverride", colorControlmoveToSaturationoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveToSaturationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveToSaturation(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("saturation"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveToSaturationCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveToSaturation", colorControlmoveToSaturationInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveSaturationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveSaturationmoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    colorControlmoveSaturationCommandParams.put(
        "moveMode", colorControlmoveSaturationmoveModeCommandParameterInfo);

    CommandParameterInfo colorControlmoveSaturationrateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    colorControlmoveSaturationCommandParams.put(
        "rate", colorControlmoveSaturationrateCommandParameterInfo);

    CommandParameterInfo colorControlmoveSaturationoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveSaturationCommandParams.put(
        "optionsMask", colorControlmoveSaturationoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveSaturationoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveSaturationCommandParams.put(
        "optionsOverride", colorControlmoveSaturationoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveSaturationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveSaturation(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveSaturationCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveSaturation", colorControlmoveSaturationInteractionInfo);
    Map<String, CommandParameterInfo> colorControlstepSaturationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlstepSaturationstepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    colorControlstepSaturationCommandParams.put(
        "stepMode", colorControlstepSaturationstepModeCommandParameterInfo);

    CommandParameterInfo colorControlstepSaturationstepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    colorControlstepSaturationCommandParams.put(
        "stepSize", colorControlstepSaturationstepSizeCommandParameterInfo);

    CommandParameterInfo colorControlstepSaturationtransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlstepSaturationCommandParams.put(
        "transitionTime", colorControlstepSaturationtransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlstepSaturationoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlstepSaturationCommandParams.put(
        "optionsMask", colorControlstepSaturationoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlstepSaturationoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlstepSaturationCommandParams.put(
        "optionsOverride", colorControlstepSaturationoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlstepSaturationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .stepSaturation(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlstepSaturationCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "stepSaturation", colorControlstepSaturationInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveToHueAndSaturationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveToHueAndSaturationhueCommandParameterInfo =
        new CommandParameterInfo("hue", Integer.class, Integer.class);
    colorControlmoveToHueAndSaturationCommandParams.put(
        "hue", colorControlmoveToHueAndSaturationhueCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueAndSaturationsaturationCommandParameterInfo =
        new CommandParameterInfo("saturation", Integer.class, Integer.class);
    colorControlmoveToHueAndSaturationCommandParams.put(
        "saturation", colorControlmoveToHueAndSaturationsaturationCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueAndSaturationtransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlmoveToHueAndSaturationCommandParams.put(
        "transitionTime", colorControlmoveToHueAndSaturationtransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueAndSaturationoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveToHueAndSaturationCommandParams.put(
        "optionsMask", colorControlmoveToHueAndSaturationoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueAndSaturationoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveToHueAndSaturationCommandParams.put(
        "optionsOverride", colorControlmoveToHueAndSaturationoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveToHueAndSaturationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveToHueAndSaturation(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("hue"),
                      (Integer) commandArguments.get("saturation"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveToHueAndSaturationCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveToHueAndSaturation", colorControlmoveToHueAndSaturationInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveToColorCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveToColorcolorXCommandParameterInfo =
        new CommandParameterInfo("colorX", Integer.class, Integer.class);
    colorControlmoveToColorCommandParams.put(
        "colorX", colorControlmoveToColorcolorXCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColorcolorYCommandParameterInfo =
        new CommandParameterInfo("colorY", Integer.class, Integer.class);
    colorControlmoveToColorCommandParams.put(
        "colorY", colorControlmoveToColorcolorYCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColortransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlmoveToColorCommandParams.put(
        "transitionTime", colorControlmoveToColortransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColoroptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveToColorCommandParams.put(
        "optionsMask", colorControlmoveToColoroptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColoroptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveToColorCommandParams.put(
        "optionsOverride", colorControlmoveToColoroptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveToColorInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveToColor(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("colorX"),
                      (Integer) commandArguments.get("colorY"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveToColorCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveToColor", colorControlmoveToColorInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveColorCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveColorrateXCommandParameterInfo =
        new CommandParameterInfo("rateX", Integer.class, Integer.class);
    colorControlmoveColorCommandParams.put("rateX", colorControlmoveColorrateXCommandParameterInfo);

    CommandParameterInfo colorControlmoveColorrateYCommandParameterInfo =
        new CommandParameterInfo("rateY", Integer.class, Integer.class);
    colorControlmoveColorCommandParams.put("rateY", colorControlmoveColorrateYCommandParameterInfo);

    CommandParameterInfo colorControlmoveColoroptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveColorCommandParams.put(
        "optionsMask", colorControlmoveColoroptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveColoroptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveColorCommandParams.put(
        "optionsOverride", colorControlmoveColoroptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveColorInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveColor(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("rateX"),
                      (Integer) commandArguments.get("rateY"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveColorCommandParams);
    colorControlClusterInteractionInfoMap.put("moveColor", colorControlmoveColorInteractionInfo);
    Map<String, CommandParameterInfo> colorControlstepColorCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlstepColorstepXCommandParameterInfo =
        new CommandParameterInfo("stepX", Integer.class, Integer.class);
    colorControlstepColorCommandParams.put("stepX", colorControlstepColorstepXCommandParameterInfo);

    CommandParameterInfo colorControlstepColorstepYCommandParameterInfo =
        new CommandParameterInfo("stepY", Integer.class, Integer.class);
    colorControlstepColorCommandParams.put("stepY", colorControlstepColorstepYCommandParameterInfo);

    CommandParameterInfo colorControlstepColortransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlstepColorCommandParams.put(
        "transitionTime", colorControlstepColortransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlstepColoroptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlstepColorCommandParams.put(
        "optionsMask", colorControlstepColoroptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlstepColoroptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlstepColorCommandParams.put(
        "optionsOverride", colorControlstepColoroptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlstepColorInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .stepColor(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepX"),
                      (Integer) commandArguments.get("stepY"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlstepColorCommandParams);
    colorControlClusterInteractionInfoMap.put("stepColor", colorControlstepColorInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveToColorTemperatureCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        colorControlmoveToColorTemperaturecolorTemperatureMiredsCommandParameterInfo =
            new CommandParameterInfo("colorTemperatureMireds", Integer.class, Integer.class);
    colorControlmoveToColorTemperatureCommandParams.put(
        "colorTemperatureMireds",
        colorControlmoveToColorTemperaturecolorTemperatureMiredsCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColorTemperaturetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlmoveToColorTemperatureCommandParams.put(
        "transitionTime", colorControlmoveToColorTemperaturetransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColorTemperatureoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveToColorTemperatureCommandParams.put(
        "optionsMask", colorControlmoveToColorTemperatureoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColorTemperatureoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveToColorTemperatureCommandParams.put(
        "optionsOverride", colorControlmoveToColorTemperatureoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveToColorTemperatureInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveToColorTemperature(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("colorTemperatureMireds"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveToColorTemperatureCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveToColorTemperature", colorControlmoveToColorTemperatureInteractionInfo);
    Map<String, CommandParameterInfo> colorControlenhancedMoveToHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlenhancedMoveToHueenhancedHueCommandParameterInfo =
        new CommandParameterInfo("enhancedHue", Integer.class, Integer.class);
    colorControlenhancedMoveToHueCommandParams.put(
        "enhancedHue", colorControlenhancedMoveToHueenhancedHueCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHuedirectionCommandParameterInfo =
        new CommandParameterInfo("direction", Integer.class, Integer.class);
    colorControlenhancedMoveToHueCommandParams.put(
        "direction", colorControlenhancedMoveToHuedirectionCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHuetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlenhancedMoveToHueCommandParams.put(
        "transitionTime", colorControlenhancedMoveToHuetransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlenhancedMoveToHueCommandParams.put(
        "optionsMask", colorControlenhancedMoveToHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlenhancedMoveToHueCommandParams.put(
        "optionsOverride", colorControlenhancedMoveToHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlenhancedMoveToHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .enhancedMoveToHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("enhancedHue"),
                      (Integer) commandArguments.get("direction"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlenhancedMoveToHueCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "enhancedMoveToHue", colorControlenhancedMoveToHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlenhancedMoveHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlenhancedMoveHuemoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    colorControlenhancedMoveHueCommandParams.put(
        "moveMode", colorControlenhancedMoveHuemoveModeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveHuerateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    colorControlenhancedMoveHueCommandParams.put(
        "rate", colorControlenhancedMoveHuerateCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlenhancedMoveHueCommandParams.put(
        "optionsMask", colorControlenhancedMoveHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlenhancedMoveHueCommandParams.put(
        "optionsOverride", colorControlenhancedMoveHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlenhancedMoveHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .enhancedMoveHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlenhancedMoveHueCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "enhancedMoveHue", colorControlenhancedMoveHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlenhancedStepHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlenhancedStepHuestepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    colorControlenhancedStepHueCommandParams.put(
        "stepMode", colorControlenhancedStepHuestepModeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedStepHuestepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    colorControlenhancedStepHueCommandParams.put(
        "stepSize", colorControlenhancedStepHuestepSizeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedStepHuetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlenhancedStepHueCommandParams.put(
        "transitionTime", colorControlenhancedStepHuetransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedStepHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlenhancedStepHueCommandParams.put(
        "optionsMask", colorControlenhancedStepHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlenhancedStepHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlenhancedStepHueCommandParams.put(
        "optionsOverride", colorControlenhancedStepHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlenhancedStepHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .enhancedStepHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlenhancedStepHueCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "enhancedStepHue", colorControlenhancedStepHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlenhancedMoveToHueAndSaturationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlenhancedMoveToHueAndSaturationenhancedHueCommandParameterInfo =
        new CommandParameterInfo("enhancedHue", Integer.class, Integer.class);
    colorControlenhancedMoveToHueAndSaturationCommandParams.put(
        "enhancedHue", colorControlenhancedMoveToHueAndSaturationenhancedHueCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHueAndSaturationsaturationCommandParameterInfo =
        new CommandParameterInfo("saturation", Integer.class, Integer.class);
    colorControlenhancedMoveToHueAndSaturationCommandParams.put(
        "saturation", colorControlenhancedMoveToHueAndSaturationsaturationCommandParameterInfo);

    CommandParameterInfo
        colorControlenhancedMoveToHueAndSaturationtransitionTimeCommandParameterInfo =
            new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlenhancedMoveToHueAndSaturationCommandParams.put(
        "transitionTime",
        colorControlenhancedMoveToHueAndSaturationtransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHueAndSaturationoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlenhancedMoveToHueAndSaturationCommandParams.put(
        "optionsMask", colorControlenhancedMoveToHueAndSaturationoptionsMaskCommandParameterInfo);

    CommandParameterInfo
        colorControlenhancedMoveToHueAndSaturationoptionsOverrideCommandParameterInfo =
            new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlenhancedMoveToHueAndSaturationCommandParams.put(
        "optionsOverride",
        colorControlenhancedMoveToHueAndSaturationoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlenhancedMoveToHueAndSaturationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .enhancedMoveToHueAndSaturation(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("enhancedHue"),
                      (Integer) commandArguments.get("saturation"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlenhancedMoveToHueAndSaturationCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "enhancedMoveToHueAndSaturation",
        colorControlenhancedMoveToHueAndSaturationInteractionInfo);
    Map<String, CommandParameterInfo> colorControlcolorLoopSetCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlcolorLoopSetupdateFlagsCommandParameterInfo =
        new CommandParameterInfo("updateFlags", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "updateFlags", colorControlcolorLoopSetupdateFlagsCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSetactionCommandParameterInfo =
        new CommandParameterInfo("action", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "action", colorControlcolorLoopSetactionCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSetdirectionCommandParameterInfo =
        new CommandParameterInfo("direction", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "direction", colorControlcolorLoopSetdirectionCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSettimeCommandParameterInfo =
        new CommandParameterInfo("time", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "time", colorControlcolorLoopSettimeCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSetstartHueCommandParameterInfo =
        new CommandParameterInfo("startHue", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "startHue", colorControlcolorLoopSetstartHueCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSetoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "optionsMask", colorControlcolorLoopSetoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSetoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "optionsOverride", colorControlcolorLoopSetoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlcolorLoopSetInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .colorLoopSet(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("updateFlags"),
                      (Integer) commandArguments.get("action"),
                      (Integer) commandArguments.get("direction"),
                      (Integer) commandArguments.get("time"),
                      (Integer) commandArguments.get("startHue"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlcolorLoopSetCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "colorLoopSet", colorControlcolorLoopSetInteractionInfo);
    Map<String, CommandParameterInfo> colorControlstopMoveStepCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlstopMoveStepoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlstopMoveStepCommandParams.put(
        "optionsMask", colorControlstopMoveStepoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlstopMoveStepoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlstopMoveStepCommandParams.put(
        "optionsOverride", colorControlstopMoveStepoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlstopMoveStepInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .stopMoveStep(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlstopMoveStepCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "stopMoveStep", colorControlstopMoveStepInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveColorTemperatureCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveColorTemperaturemoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "moveMode", colorControlmoveColorTemperaturemoveModeCommandParameterInfo);

    CommandParameterInfo colorControlmoveColorTemperaturerateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "rate", colorControlmoveColorTemperaturerateCommandParameterInfo);

    CommandParameterInfo
        colorControlmoveColorTemperaturecolorTemperatureMinimumMiredsCommandParameterInfo =
            new CommandParameterInfo("colorTemperatureMinimumMireds", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "colorTemperatureMinimumMireds",
        colorControlmoveColorTemperaturecolorTemperatureMinimumMiredsCommandParameterInfo);

    CommandParameterInfo
        colorControlmoveColorTemperaturecolorTemperatureMaximumMiredsCommandParameterInfo =
            new CommandParameterInfo("colorTemperatureMaximumMireds", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "colorTemperatureMaximumMireds",
        colorControlmoveColorTemperaturecolorTemperatureMaximumMiredsCommandParameterInfo);

    CommandParameterInfo colorControlmoveColorTemperatureoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "optionsMask", colorControlmoveColorTemperatureoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveColorTemperatureoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "optionsOverride", colorControlmoveColorTemperatureoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveColorTemperatureInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveColorTemperature(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("colorTemperatureMinimumMireds"),
                      (Integer) commandArguments.get("colorTemperatureMaximumMireds"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveColorTemperatureCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveColorTemperature", colorControlmoveColorTemperatureInteractionInfo);
    Map<String, CommandParameterInfo> colorControlstepColorTemperatureCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlstepColorTemperaturestepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "stepMode", colorControlstepColorTemperaturestepModeCommandParameterInfo);

    CommandParameterInfo colorControlstepColorTemperaturestepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "stepSize", colorControlstepColorTemperaturestepSizeCommandParameterInfo);

    CommandParameterInfo colorControlstepColorTemperaturetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "transitionTime", colorControlstepColorTemperaturetransitionTimeCommandParameterInfo);

    CommandParameterInfo
        colorControlstepColorTemperaturecolorTemperatureMinimumMiredsCommandParameterInfo =
            new CommandParameterInfo("colorTemperatureMinimumMireds", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "colorTemperatureMinimumMireds",
        colorControlstepColorTemperaturecolorTemperatureMinimumMiredsCommandParameterInfo);

    CommandParameterInfo
        colorControlstepColorTemperaturecolorTemperatureMaximumMiredsCommandParameterInfo =
            new CommandParameterInfo("colorTemperatureMaximumMireds", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "colorTemperatureMaximumMireds",
        colorControlstepColorTemperaturecolorTemperatureMaximumMiredsCommandParameterInfo);

    CommandParameterInfo colorControlstepColorTemperatureoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "optionsMask", colorControlstepColorTemperatureoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlstepColorTemperatureoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "optionsOverride", colorControlstepColorTemperatureoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlstepColorTemperatureInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .stepColorTemperature(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("colorTemperatureMinimumMireds"),
                      (Integer) commandArguments.get("colorTemperatureMaximumMireds"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlstepColorTemperatureCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "stepColorTemperature", colorControlstepColorTemperatureInteractionInfo);
    commandMap.put("colorControl", colorControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> ballastConfigurationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("ballastConfiguration", ballastConfigurationClusterInteractionInfoMap);
    Map<String, InteractionInfo> illuminanceMeasurementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("illuminanceMeasurement", illuminanceMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> temperatureMeasurementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("temperatureMeasurement", temperatureMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> pressureMeasurementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("pressureMeasurement", pressureMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> flowMeasurementClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("flowMeasurement", flowMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> relativeHumidityMeasurementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put(
        "relativeHumidityMeasurement", relativeHumidityMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> occupancySensingClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("occupancySensing", occupancySensingClusterInteractionInfoMap);
    Map<String, InteractionInfo> wakeOnLanClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("wakeOnLan", wakeOnLanClusterInteractionInfoMap);
    Map<String, InteractionInfo> channelClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> channelchangeChannelCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo channelchangeChannelmatchCommandParameterInfo =
        new CommandParameterInfo("match", String.class, String.class);
    channelchangeChannelCommandParams.put("match", channelchangeChannelmatchCommandParameterInfo);

    InteractionInfo channelchangeChannelInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ChannelCluster) cluster)
                  .changeChannel(
                      (ChipClusters.ChannelCluster.ChangeChannelResponseCallback) callback,
                      (String) commandArguments.get("match"));
            },
            () -> new DelegatedChannelClusterChangeChannelResponseCallback(),
            channelchangeChannelCommandParams);
    channelClusterInteractionInfoMap.put("changeChannel", channelchangeChannelInteractionInfo);
    Map<String, CommandParameterInfo> channelchangeChannelByNumberCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo channelchangeChannelByNumbermajorNumberCommandParameterInfo =
        new CommandParameterInfo("majorNumber", Integer.class, Integer.class);
    channelchangeChannelByNumberCommandParams.put(
        "majorNumber", channelchangeChannelByNumbermajorNumberCommandParameterInfo);

    CommandParameterInfo channelchangeChannelByNumberminorNumberCommandParameterInfo =
        new CommandParameterInfo("minorNumber", Integer.class, Integer.class);
    channelchangeChannelByNumberCommandParams.put(
        "minorNumber", channelchangeChannelByNumberminorNumberCommandParameterInfo);

    InteractionInfo channelchangeChannelByNumberInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ChannelCluster) cluster)
                  .changeChannelByNumber(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("majorNumber"),
                      (Integer) commandArguments.get("minorNumber"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            channelchangeChannelByNumberCommandParams);
    channelClusterInteractionInfoMap.put(
        "changeChannelByNumber", channelchangeChannelByNumberInteractionInfo);
    Map<String, CommandParameterInfo> channelskipChannelCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo channelskipChannelcountCommandParameterInfo =
        new CommandParameterInfo("count", Integer.class, Integer.class);
    channelskipChannelCommandParams.put("count", channelskipChannelcountCommandParameterInfo);

    InteractionInfo channelskipChannelInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ChannelCluster) cluster)
                  .skipChannel(
                      (DefaultClusterCallback) callback, (Integer) commandArguments.get("count"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            channelskipChannelCommandParams);
    channelClusterInteractionInfoMap.put("skipChannel", channelskipChannelInteractionInfo);
    commandMap.put("channel", channelClusterInteractionInfoMap);
    Map<String, InteractionInfo> targetNavigatorClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> targetNavigatornavigateTargetCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo targetNavigatornavigateTargettargetCommandParameterInfo =
        new CommandParameterInfo("target", Integer.class, Integer.class);
    targetNavigatornavigateTargetCommandParams.put(
        "target", targetNavigatornavigateTargettargetCommandParameterInfo);

    CommandParameterInfo targetNavigatornavigateTargetdataCommandParameterInfo =
        new CommandParameterInfo("data", Optional.class, String.class);
    targetNavigatornavigateTargetCommandParams.put(
        "data", targetNavigatornavigateTargetdataCommandParameterInfo);

    InteractionInfo targetNavigatornavigateTargetInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TargetNavigatorCluster) cluster)
                  .navigateTarget(
                      (ChipClusters.TargetNavigatorCluster.NavigateTargetResponseCallback) callback,
                      (Integer) commandArguments.get("target"),
                      (Optional<String>) commandArguments.get("data"));
            },
            () -> new DelegatedTargetNavigatorClusterNavigateTargetResponseCallback(),
            targetNavigatornavigateTargetCommandParams);
    targetNavigatorClusterInteractionInfoMap.put(
        "navigateTarget", targetNavigatornavigateTargetInteractionInfo);
    commandMap.put("targetNavigator", targetNavigatorClusterInteractionInfoMap);
    Map<String, InteractionInfo> mediaPlaybackClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> mediaPlaybackplayCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackplayInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .play((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedMediaPlaybackClusterPlaybackResponseCallback(),
            mediaPlaybackplayCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("play", mediaPlaybackplayInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackpauseCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackpauseInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .pause((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedMediaPlaybackClusterPlaybackResponseCallback(),
            mediaPlaybackpauseCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("pause", mediaPlaybackpauseInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackstopCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackstopInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .stop((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedMediaPlaybackClusterPlaybackResponseCallback(),
            mediaPlaybackstopCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("stop", mediaPlaybackstopInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackstartOverCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackstartOverInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .startOver((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedMediaPlaybackClusterPlaybackResponseCallback(),
            mediaPlaybackstartOverCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("startOver", mediaPlaybackstartOverInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackpreviousCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackpreviousInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .previous((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedMediaPlaybackClusterPlaybackResponseCallback(),
            mediaPlaybackpreviousCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("previous", mediaPlaybackpreviousInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybacknextCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybacknextInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .next((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedMediaPlaybackClusterPlaybackResponseCallback(),
            mediaPlaybacknextCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("next", mediaPlaybacknextInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackrewindCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackrewindInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .rewind((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedMediaPlaybackClusterPlaybackResponseCallback(),
            mediaPlaybackrewindCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("rewind", mediaPlaybackrewindInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackfastForwardCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackfastForwardInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .fastForward(
                      (ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedMediaPlaybackClusterPlaybackResponseCallback(),
            mediaPlaybackfastForwardCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put(
        "fastForward", mediaPlaybackfastForwardInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackskipForwardCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo mediaPlaybackskipForwarddeltaPositionMillisecondsCommandParameterInfo =
        new CommandParameterInfo("deltaPositionMilliseconds", Long.class, Long.class);
    mediaPlaybackskipForwardCommandParams.put(
        "deltaPositionMilliseconds",
        mediaPlaybackskipForwarddeltaPositionMillisecondsCommandParameterInfo);

    InteractionInfo mediaPlaybackskipForwardInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .skipForward(
                      (ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback,
                      (Long) commandArguments.get("deltaPositionMilliseconds"));
            },
            () -> new DelegatedMediaPlaybackClusterPlaybackResponseCallback(),
            mediaPlaybackskipForwardCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put(
        "skipForward", mediaPlaybackskipForwardInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackskipBackwardCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo mediaPlaybackskipBackwarddeltaPositionMillisecondsCommandParameterInfo =
        new CommandParameterInfo("deltaPositionMilliseconds", Long.class, Long.class);
    mediaPlaybackskipBackwardCommandParams.put(
        "deltaPositionMilliseconds",
        mediaPlaybackskipBackwarddeltaPositionMillisecondsCommandParameterInfo);

    InteractionInfo mediaPlaybackskipBackwardInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .skipBackward(
                      (ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback,
                      (Long) commandArguments.get("deltaPositionMilliseconds"));
            },
            () -> new DelegatedMediaPlaybackClusterPlaybackResponseCallback(),
            mediaPlaybackskipBackwardCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put(
        "skipBackward", mediaPlaybackskipBackwardInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackseekCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo mediaPlaybackseekpositionCommandParameterInfo =
        new CommandParameterInfo("position", Long.class, Long.class);
    mediaPlaybackseekCommandParams.put("position", mediaPlaybackseekpositionCommandParameterInfo);

    InteractionInfo mediaPlaybackseekInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .seek(
                      (ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback,
                      (Long) commandArguments.get("position"));
            },
            () -> new DelegatedMediaPlaybackClusterPlaybackResponseCallback(),
            mediaPlaybackseekCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("seek", mediaPlaybackseekInteractionInfo);
    commandMap.put("mediaPlayback", mediaPlaybackClusterInteractionInfoMap);
    Map<String, InteractionInfo> mediaInputClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> mediaInputselectInputCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo mediaInputselectInputindexCommandParameterInfo =
        new CommandParameterInfo("index", Integer.class, Integer.class);
    mediaInputselectInputCommandParams.put("index", mediaInputselectInputindexCommandParameterInfo);

    InteractionInfo mediaInputselectInputInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaInputCluster) cluster)
                  .selectInput(
                      (DefaultClusterCallback) callback, (Integer) commandArguments.get("index"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            mediaInputselectInputCommandParams);
    mediaInputClusterInteractionInfoMap.put("selectInput", mediaInputselectInputInteractionInfo);
    Map<String, CommandParameterInfo> mediaInputshowInputStatusCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaInputshowInputStatusInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaInputCluster) cluster)
                  .showInputStatus((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            mediaInputshowInputStatusCommandParams);
    mediaInputClusterInteractionInfoMap.put(
        "showInputStatus", mediaInputshowInputStatusInteractionInfo);
    Map<String, CommandParameterInfo> mediaInputhideInputStatusCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaInputhideInputStatusInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaInputCluster) cluster)
                  .hideInputStatus((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            mediaInputhideInputStatusCommandParams);
    mediaInputClusterInteractionInfoMap.put(
        "hideInputStatus", mediaInputhideInputStatusInteractionInfo);
    Map<String, CommandParameterInfo> mediaInputrenameInputCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo mediaInputrenameInputindexCommandParameterInfo =
        new CommandParameterInfo("index", Integer.class, Integer.class);
    mediaInputrenameInputCommandParams.put("index", mediaInputrenameInputindexCommandParameterInfo);

    CommandParameterInfo mediaInputrenameInputnameCommandParameterInfo =
        new CommandParameterInfo("name", String.class, String.class);
    mediaInputrenameInputCommandParams.put("name", mediaInputrenameInputnameCommandParameterInfo);

    InteractionInfo mediaInputrenameInputInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaInputCluster) cluster)
                  .renameInput(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("index"),
                      (String) commandArguments.get("name"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            mediaInputrenameInputCommandParams);
    mediaInputClusterInteractionInfoMap.put("renameInput", mediaInputrenameInputInteractionInfo);
    commandMap.put("mediaInput", mediaInputClusterInteractionInfoMap);
    Map<String, InteractionInfo> lowPowerClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> lowPowersleepCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo lowPowersleepInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LowPowerCluster) cluster).sleep((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            lowPowersleepCommandParams);
    lowPowerClusterInteractionInfoMap.put("sleep", lowPowersleepInteractionInfo);
    commandMap.put("lowPower", lowPowerClusterInteractionInfoMap);
    Map<String, InteractionInfo> keypadInputClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> keypadInputsendKeyCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo keypadInputsendKeykeyCodeCommandParameterInfo =
        new CommandParameterInfo("keyCode", Integer.class, Integer.class);
    keypadInputsendKeyCommandParams.put("keyCode", keypadInputsendKeykeyCodeCommandParameterInfo);

    InteractionInfo keypadInputsendKeyInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.KeypadInputCluster) cluster)
                  .sendKey(
                      (ChipClusters.KeypadInputCluster.SendKeyResponseCallback) callback,
                      (Integer) commandArguments.get("keyCode"));
            },
            () -> new DelegatedKeypadInputClusterSendKeyResponseCallback(),
            keypadInputsendKeyCommandParams);
    keypadInputClusterInteractionInfoMap.put("sendKey", keypadInputsendKeyInteractionInfo);
    commandMap.put("keypadInput", keypadInputClusterInteractionInfoMap);
    Map<String, InteractionInfo> contentLauncherClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> contentLauncherlaunchContentCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo contentLauncherlaunchContentautoPlayCommandParameterInfo =
        new CommandParameterInfo("autoPlay", Boolean.class, Boolean.class);
    contentLauncherlaunchContentCommandParams.put(
        "autoPlay", contentLauncherlaunchContentautoPlayCommandParameterInfo);

    CommandParameterInfo contentLauncherlaunchContentdataCommandParameterInfo =
        new CommandParameterInfo("data", Optional.class, String.class);
    contentLauncherlaunchContentCommandParams.put(
        "data", contentLauncherlaunchContentdataCommandParameterInfo);

    InteractionInfo contentLauncherlaunchContentInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ContentLauncherCluster) cluster)
                  .launchContent(
                      (ChipClusters.ContentLauncherCluster.LauncherResponseCallback) callback,
                      (ChipStructs.ContentLauncherClusterContentSearchStruct)
                          commandArguments.get("search"),
                      (Boolean) commandArguments.get("autoPlay"),
                      (Optional<String>) commandArguments.get("data"));
            },
            () -> new DelegatedContentLauncherClusterLauncherResponseCallback(),
            contentLauncherlaunchContentCommandParams);
    contentLauncherClusterInteractionInfoMap.put(
        "launchContent", contentLauncherlaunchContentInteractionInfo);
    Map<String, CommandParameterInfo> contentLauncherlaunchURLCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo contentLauncherlaunchURLcontentURLCommandParameterInfo =
        new CommandParameterInfo("contentURL", String.class, String.class);
    contentLauncherlaunchURLCommandParams.put(
        "contentURL", contentLauncherlaunchURLcontentURLCommandParameterInfo);

    CommandParameterInfo contentLauncherlaunchURLdisplayStringCommandParameterInfo =
        new CommandParameterInfo("displayString", Optional.class, String.class);
    contentLauncherlaunchURLCommandParams.put(
        "displayString", contentLauncherlaunchURLdisplayStringCommandParameterInfo);

    InteractionInfo contentLauncherlaunchURLInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ContentLauncherCluster) cluster)
                  .launchURL(
                      (ChipClusters.ContentLauncherCluster.LauncherResponseCallback) callback,
                      (String) commandArguments.get("contentURL"),
                      (Optional<String>) commandArguments.get("displayString"),
                      (Optional<ChipStructs.ContentLauncherClusterBrandingInformationStruct>)
                          commandArguments.get("brandingInformation"));
            },
            () -> new DelegatedContentLauncherClusterLauncherResponseCallback(),
            contentLauncherlaunchURLCommandParams);
    contentLauncherClusterInteractionInfoMap.put(
        "launchURL", contentLauncherlaunchURLInteractionInfo);
    commandMap.put("contentLauncher", contentLauncherClusterInteractionInfoMap);
    Map<String, InteractionInfo> audioOutputClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> audioOutputselectOutputCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo audioOutputselectOutputindexCommandParameterInfo =
        new CommandParameterInfo("index", Integer.class, Integer.class);
    audioOutputselectOutputCommandParams.put(
        "index", audioOutputselectOutputindexCommandParameterInfo);

    InteractionInfo audioOutputselectOutputInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AudioOutputCluster) cluster)
                  .selectOutput(
                      (DefaultClusterCallback) callback, (Integer) commandArguments.get("index"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            audioOutputselectOutputCommandParams);
    audioOutputClusterInteractionInfoMap.put(
        "selectOutput", audioOutputselectOutputInteractionInfo);
    Map<String, CommandParameterInfo> audioOutputrenameOutputCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo audioOutputrenameOutputindexCommandParameterInfo =
        new CommandParameterInfo("index", Integer.class, Integer.class);
    audioOutputrenameOutputCommandParams.put(
        "index", audioOutputrenameOutputindexCommandParameterInfo);

    CommandParameterInfo audioOutputrenameOutputnameCommandParameterInfo =
        new CommandParameterInfo("name", String.class, String.class);
    audioOutputrenameOutputCommandParams.put(
        "name", audioOutputrenameOutputnameCommandParameterInfo);

    InteractionInfo audioOutputrenameOutputInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AudioOutputCluster) cluster)
                  .renameOutput(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("index"),
                      (String) commandArguments.get("name"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            audioOutputrenameOutputCommandParams);
    audioOutputClusterInteractionInfoMap.put(
        "renameOutput", audioOutputrenameOutputInteractionInfo);
    commandMap.put("audioOutput", audioOutputClusterInteractionInfoMap);
    Map<String, InteractionInfo> applicationLauncherClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> applicationLauncherlaunchAppCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo applicationLauncherlaunchAppdataCommandParameterInfo =
        new CommandParameterInfo("data", Optional.class, byte[].class);
    applicationLauncherlaunchAppCommandParams.put(
        "data", applicationLauncherlaunchAppdataCommandParameterInfo);

    InteractionInfo applicationLauncherlaunchAppInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ApplicationLauncherCluster) cluster)
                  .launchApp(
                      (ChipClusters.ApplicationLauncherCluster.LauncherResponseCallback) callback,
                      (Optional<ChipStructs.ApplicationLauncherClusterApplicationStruct>)
                          commandArguments.get("application"),
                      (Optional<byte[]>) commandArguments.get("data"));
            },
            () -> new DelegatedApplicationLauncherClusterLauncherResponseCallback(),
            applicationLauncherlaunchAppCommandParams);
    applicationLauncherClusterInteractionInfoMap.put(
        "launchApp", applicationLauncherlaunchAppInteractionInfo);
    Map<String, CommandParameterInfo> applicationLauncherstopAppCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo applicationLauncherstopAppInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ApplicationLauncherCluster) cluster)
                  .stopApp(
                      (ChipClusters.ApplicationLauncherCluster.LauncherResponseCallback) callback,
                      (Optional<ChipStructs.ApplicationLauncherClusterApplicationStruct>)
                          commandArguments.get("application"));
            },
            () -> new DelegatedApplicationLauncherClusterLauncherResponseCallback(),
            applicationLauncherstopAppCommandParams);
    applicationLauncherClusterInteractionInfoMap.put(
        "stopApp", applicationLauncherstopAppInteractionInfo);
    Map<String, CommandParameterInfo> applicationLauncherhideAppCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo applicationLauncherhideAppInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ApplicationLauncherCluster) cluster)
                  .hideApp(
                      (ChipClusters.ApplicationLauncherCluster.LauncherResponseCallback) callback,
                      (Optional<ChipStructs.ApplicationLauncherClusterApplicationStruct>)
                          commandArguments.get("application"));
            },
            () -> new DelegatedApplicationLauncherClusterLauncherResponseCallback(),
            applicationLauncherhideAppCommandParams);
    applicationLauncherClusterInteractionInfoMap.put(
        "hideApp", applicationLauncherhideAppInteractionInfo);
    commandMap.put("applicationLauncher", applicationLauncherClusterInteractionInfoMap);
    Map<String, InteractionInfo> applicationBasicClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("applicationBasic", applicationBasicClusterInteractionInfoMap);
    Map<String, InteractionInfo> accountLoginClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> accountLogingetSetupPINCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo accountLogingetSetupPINtempAccountIdentifierCommandParameterInfo =
        new CommandParameterInfo("tempAccountIdentifier", String.class, String.class);
    accountLogingetSetupPINCommandParams.put(
        "tempAccountIdentifier", accountLogingetSetupPINtempAccountIdentifierCommandParameterInfo);

    InteractionInfo accountLogingetSetupPINInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AccountLoginCluster) cluster)
                  .getSetupPIN(
                      (ChipClusters.AccountLoginCluster.GetSetupPINResponseCallback) callback,
                      (String) commandArguments.get("tempAccountIdentifier"),
                      10000);
            },
            () -> new DelegatedAccountLoginClusterGetSetupPINResponseCallback(),
            accountLogingetSetupPINCommandParams);
    accountLoginClusterInteractionInfoMap.put(
        "getSetupPIN", accountLogingetSetupPINInteractionInfo);
    Map<String, CommandParameterInfo> accountLoginloginCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo accountLoginlogintempAccountIdentifierCommandParameterInfo =
        new CommandParameterInfo("tempAccountIdentifier", String.class, String.class);
    accountLoginloginCommandParams.put(
        "tempAccountIdentifier", accountLoginlogintempAccountIdentifierCommandParameterInfo);

    CommandParameterInfo accountLoginloginsetupPINCommandParameterInfo =
        new CommandParameterInfo("setupPIN", String.class, String.class);
    accountLoginloginCommandParams.put("setupPIN", accountLoginloginsetupPINCommandParameterInfo);

    InteractionInfo accountLoginloginInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AccountLoginCluster) cluster)
                  .login(
                      (DefaultClusterCallback) callback,
                      (String) commandArguments.get("tempAccountIdentifier"),
                      (String) commandArguments.get("setupPIN"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            accountLoginloginCommandParams);
    accountLoginClusterInteractionInfoMap.put("login", accountLoginloginInteractionInfo);
    Map<String, CommandParameterInfo> accountLoginlogoutCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo accountLoginlogoutInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AccountLoginCluster) cluster)
                  .logout((DefaultClusterCallback) callback, 10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            accountLoginlogoutCommandParams);
    accountLoginClusterInteractionInfoMap.put("logout", accountLoginlogoutInteractionInfo);
    commandMap.put("accountLogin", accountLoginClusterInteractionInfoMap);
    Map<String, InteractionInfo> electricalMeasurementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("electricalMeasurement", electricalMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> unitTestingClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> unitTestingtestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster).test((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            unitTestingtestCommandParams);
    unitTestingClusterInteractionInfoMap.put("test", unitTestingtestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestNotHandledCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestNotHandledInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testNotHandled((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            unitTestingtestNotHandledCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testNotHandled", unitTestingtestNotHandledInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestSpecificCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestSpecificInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testSpecific(
                      (ChipClusters.UnitTestingCluster.TestSpecificResponseCallback) callback);
            },
            () -> new DelegatedUnitTestingClusterTestSpecificResponseCallback(),
            unitTestingtestSpecificCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testSpecific", unitTestingtestSpecificInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestUnknownCommandCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestUnknownCommandInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testUnknownCommand((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            unitTestingtestUnknownCommandCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testUnknownCommand", unitTestingtestUnknownCommandInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestAddArgumentsCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestAddArgumentsarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Integer.class, Integer.class);
    unitTestingtestAddArgumentsCommandParams.put(
        "arg1", unitTestingtestAddArgumentsarg1CommandParameterInfo);

    CommandParameterInfo unitTestingtestAddArgumentsarg2CommandParameterInfo =
        new CommandParameterInfo("arg2", Integer.class, Integer.class);
    unitTestingtestAddArgumentsCommandParams.put(
        "arg2", unitTestingtestAddArgumentsarg2CommandParameterInfo);

    InteractionInfo unitTestingtestAddArgumentsInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testAddArguments(
                      (ChipClusters.UnitTestingCluster.TestAddArgumentsResponseCallback) callback,
                      (Integer) commandArguments.get("arg1"),
                      (Integer) commandArguments.get("arg2"));
            },
            () -> new DelegatedUnitTestingClusterTestAddArgumentsResponseCallback(),
            unitTestingtestAddArgumentsCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testAddArguments", unitTestingtestAddArgumentsInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestStructArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestStructArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testStructArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ChipStructs.UnitTestingClusterSimpleStruct) commandArguments.get("arg1"));
            },
            () -> new DelegatedUnitTestingClusterBooleanResponseCallback(),
            unitTestingtestStructArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testStructArgumentRequest", unitTestingtestStructArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestNestedStructArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestNestedStructArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testNestedStructArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ChipStructs.UnitTestingClusterNestedStruct) commandArguments.get("arg1"));
            },
            () -> new DelegatedUnitTestingClusterBooleanResponseCallback(),
            unitTestingtestNestedStructArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testNestedStructArgumentRequest",
        unitTestingtestNestedStructArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestListStructArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestListStructArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testListStructArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ArrayList<ChipStructs.UnitTestingClusterSimpleStruct>)
                          commandArguments.get("arg1"));
            },
            () -> new DelegatedUnitTestingClusterBooleanResponseCallback(),
            unitTestingtestListStructArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testListStructArgumentRequest", unitTestingtestListStructArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestListInt8UArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestListInt8UArgumentRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", ArrayList.class, Integer.class);
    unitTestingtestListInt8UArgumentRequestCommandParams.put(
        "arg1", unitTestingtestListInt8UArgumentRequestarg1CommandParameterInfo);

    InteractionInfo unitTestingtestListInt8UArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testListInt8UArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ArrayList<Integer>) commandArguments.get("arg1"));
            },
            () -> new DelegatedUnitTestingClusterBooleanResponseCallback(),
            unitTestingtestListInt8UArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testListInt8UArgumentRequest", unitTestingtestListInt8UArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestNestedStructListArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestNestedStructListArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testNestedStructListArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ChipStructs.UnitTestingClusterNestedStructList)
                          commandArguments.get("arg1"));
            },
            () -> new DelegatedUnitTestingClusterBooleanResponseCallback(),
            unitTestingtestNestedStructListArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testNestedStructListArgumentRequest",
        unitTestingtestNestedStructListArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo>
        unitTestingtestListNestedStructListArgumentRequestCommandParams =
            new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestListNestedStructListArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testListNestedStructListArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ArrayList<ChipStructs.UnitTestingClusterNestedStructList>)
                          commandArguments.get("arg1"));
            },
            () -> new DelegatedUnitTestingClusterBooleanResponseCallback(),
            unitTestingtestListNestedStructListArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testListNestedStructListArgumentRequest",
        unitTestingtestListNestedStructListArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestListInt8UReverseRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestListInt8UReverseRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", ArrayList.class, Integer.class);
    unitTestingtestListInt8UReverseRequestCommandParams.put(
        "arg1", unitTestingtestListInt8UReverseRequestarg1CommandParameterInfo);

    InteractionInfo unitTestingtestListInt8UReverseRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testListInt8UReverseRequest(
                      (ChipClusters.UnitTestingCluster.TestListInt8UReverseResponseCallback)
                          callback,
                      (ArrayList<Integer>) commandArguments.get("arg1"));
            },
            () -> new DelegatedUnitTestingClusterTestListInt8UReverseResponseCallback(),
            unitTestingtestListInt8UReverseRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testListInt8UReverseRequest", unitTestingtestListInt8UReverseRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestEnumsRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestEnumsRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Integer.class, Integer.class);
    unitTestingtestEnumsRequestCommandParams.put(
        "arg1", unitTestingtestEnumsRequestarg1CommandParameterInfo);

    CommandParameterInfo unitTestingtestEnumsRequestarg2CommandParameterInfo =
        new CommandParameterInfo("arg2", Integer.class, Integer.class);
    unitTestingtestEnumsRequestCommandParams.put(
        "arg2", unitTestingtestEnumsRequestarg2CommandParameterInfo);

    InteractionInfo unitTestingtestEnumsRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testEnumsRequest(
                      (ChipClusters.UnitTestingCluster.TestEnumsResponseCallback) callback,
                      (Integer) commandArguments.get("arg1"),
                      (Integer) commandArguments.get("arg2"));
            },
            () -> new DelegatedUnitTestingClusterTestEnumsResponseCallback(),
            unitTestingtestEnumsRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testEnumsRequest", unitTestingtestEnumsRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestNullableOptionalRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestNullableOptionalRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Optional.class, Integer.class);
    unitTestingtestNullableOptionalRequestCommandParams.put(
        "arg1", unitTestingtestNullableOptionalRequestarg1CommandParameterInfo);

    InteractionInfo unitTestingtestNullableOptionalRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testNullableOptionalRequest(
                      (ChipClusters.UnitTestingCluster.TestNullableOptionalResponseCallback)
                          callback,
                      (Optional<Integer>) commandArguments.get("arg1"));
            },
            () -> new DelegatedUnitTestingClusterTestNullableOptionalResponseCallback(),
            unitTestingtestNullableOptionalRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testNullableOptionalRequest", unitTestingtestNullableOptionalRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingsimpleStructEchoRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingsimpleStructEchoRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .simpleStructEchoRequest(
                      (ChipClusters.UnitTestingCluster.SimpleStructResponseCallback) callback,
                      (ChipStructs.UnitTestingClusterSimpleStruct) commandArguments.get("arg1"));
            },
            () -> new DelegatedUnitTestingClusterSimpleStructResponseCallback(),
            unitTestingsimpleStructEchoRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "simpleStructEchoRequest", unitTestingsimpleStructEchoRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtimedInvokeRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtimedInvokeRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .timedInvokeRequest((DefaultClusterCallback) callback, 10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            unitTestingtimedInvokeRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "timedInvokeRequest", unitTestingtimedInvokeRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestSimpleOptionalArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestSimpleOptionalArgumentRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Optional.class, Boolean.class);
    unitTestingtestSimpleOptionalArgumentRequestCommandParams.put(
        "arg1", unitTestingtestSimpleOptionalArgumentRequestarg1CommandParameterInfo);

    InteractionInfo unitTestingtestSimpleOptionalArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testSimpleOptionalArgumentRequest(
                      (DefaultClusterCallback) callback,
                      (Optional<Boolean>) commandArguments.get("arg1"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            unitTestingtestSimpleOptionalArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testSimpleOptionalArgumentRequest",
        unitTestingtestSimpleOptionalArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestEmitTestEventRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestEmitTestEventRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Integer.class, Integer.class);
    unitTestingtestEmitTestEventRequestCommandParams.put(
        "arg1", unitTestingtestEmitTestEventRequestarg1CommandParameterInfo);

    CommandParameterInfo unitTestingtestEmitTestEventRequestarg2CommandParameterInfo =
        new CommandParameterInfo("arg2", Integer.class, Integer.class);
    unitTestingtestEmitTestEventRequestCommandParams.put(
        "arg2", unitTestingtestEmitTestEventRequestarg2CommandParameterInfo);

    CommandParameterInfo unitTestingtestEmitTestEventRequestarg3CommandParameterInfo =
        new CommandParameterInfo("arg3", Boolean.class, Boolean.class);
    unitTestingtestEmitTestEventRequestCommandParams.put(
        "arg3", unitTestingtestEmitTestEventRequestarg3CommandParameterInfo);

    InteractionInfo unitTestingtestEmitTestEventRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testEmitTestEventRequest(
                      (ChipClusters.UnitTestingCluster.TestEmitTestEventResponseCallback) callback,
                      (Integer) commandArguments.get("arg1"),
                      (Integer) commandArguments.get("arg2"),
                      (Boolean) commandArguments.get("arg3"));
            },
            () -> new DelegatedUnitTestingClusterTestEmitTestEventResponseCallback(),
            unitTestingtestEmitTestEventRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testEmitTestEventRequest", unitTestingtestEmitTestEventRequestInteractionInfo);
    commandMap.put("unitTesting", unitTestingClusterInteractionInfoMap);
    Map<String, InteractionInfo> faultInjectionClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("faultInjection", faultInjectionClusterInteractionInfoMap);
    return commandMap;
  }
}
