/*
 *
 *    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 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 DelegatedAddGroupResponseCallback
      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 DelegatedViewGroupResponseCallback
      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 DelegatedGetGroupMembershipResponseCallback
      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 DelegatedRemoveGroupResponseCallback
      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 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 DelegatedAddSceneResponseCallback
      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 DelegatedViewSceneResponseCallback
      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 DelegatedRemoveSceneResponseCallback
      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 DelegatedRemoveAllScenesResponseCallback
      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 DelegatedStoreSceneResponseCallback
      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 DelegatedGetSceneMembershipResponseCallback
      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 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 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 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 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 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 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 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 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 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 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 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.AccessControlClusterAccessControlEntry> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.AccessControlClusterAccessControlEntry>");
      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.AccessControlClusterExtensionEntry> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.AccessControlClusterExtensionEntry>");
      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 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 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 DelegatedBasicClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BasicCluster.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 DelegatedBasicClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BasicCluster.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 DelegatedBasicClusterAttributeListAttributeCallback
      implements ChipClusters.BasicCluster.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 DelegatedQueryImageResponseCallback
      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 DelegatedApplyUpdateResponseCallback
      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 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 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 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 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 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 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 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 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 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 DelegatedArmFailSafeResponseCallback
      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 DelegatedSetRegulatoryConfigResponseCallback
      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 DelegatedCommissioningCompleteResponseCallback
      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 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 DelegatedScanNetworksResponseCallback
      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 DelegatedNetworkConfigResponseCallback
      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 DelegatedConnectNetworkResponseCallback
      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 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 DelegatedRetrieveLogsResponseCallback
      implements ChipClusters.DiagnosticLogsCluster.RetrieveLogsResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(Integer status, byte[] content, Long timeStamp, Long timeSinceBoot) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo contentResponseValue = new CommandResponseInfo("content", "byte[]");
      responseValues.put(contentResponseValue, content);
      CommandResponseInfo timeStampResponseValue = new CommandResponseInfo("timeStamp", "Long");
      responseValues.put(timeStampResponseValue, timeStamp);
      CommandResponseInfo timeSinceBootResponseValue =
          new CommandResponseInfo("timeSinceBoot", "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 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.GeneralDiagnosticsClusterNetworkInterfaceType> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.GeneralDiagnosticsClusterNetworkInterfaceType>");
      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 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.SoftwareDiagnosticsClusterThreadMetrics> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.SoftwareDiagnosticsClusterThreadMetrics>");
      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 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 DelegatedThreadNetworkDiagnosticsClusterNeighborTableListAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.NeighborTableListAttributeCallback,
          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 DelegatedThreadNetworkDiagnosticsClusterRouteTableListAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.RouteTableListAttributeCallback,
          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 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 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 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 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 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 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 DelegatedBridgedDeviceBasicClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BridgedDeviceBasicCluster.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 DelegatedBridgedDeviceBasicClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BridgedDeviceBasicCluster.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 DelegatedBridgedDeviceBasicClusterAttributeListAttributeCallback
      implements ChipClusters.BridgedDeviceBasicCluster.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 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 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 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 DelegatedAttestationResponseCallback
      implements ChipClusters.OperationalCredentialsCluster.AttestationResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedCertificateChainResponseCallback
      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 DelegatedCSRResponseCallback
      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 DelegatedNOCResponseCallback
      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.OperationalCredentialsClusterFabricDescriptor> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.OperationalCredentialsClusterFabricDescriptor>");
      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 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 DelegatedKeySetReadResponseCallback
      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 DelegatedKeySetReadAllIndicesResponseCallback
      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 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 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 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 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 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 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 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 DelegatedGetWeekDayScheduleResponseCallback
      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 DelegatedGetYearDayScheduleResponseCallback
      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 DelegatedGetHolidayScheduleResponseCallback
      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 DelegatedGetUserResponseCallback
      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.DoorLockClusterDlCredential> 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 DelegatedSetCredentialResponseCallback
      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 DelegatedGetCredentialStatusResponseCallback
      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 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 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 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 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 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 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 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 DelegatedGetWeeklyScheduleResponseCallback
      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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 DelegatedChangeChannelResponseCallback
      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.ChannelClusterChannelInfo> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<ChipStructs.ChannelClusterChannelInfo>");
      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 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 DelegatedNavigateTargetResponseCallback
      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.TargetNavigatorClusterTargetInfo> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.TargetNavigatorClusterTargetInfo>");
      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 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 DelegatedPlaybackResponseCallback
      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 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 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.MediaInputClusterInputInfo> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<ChipStructs.MediaInputClusterInputInfo>");
      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 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 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 DelegatedSendKeyResponseCallback
      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 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 DelegatedLaunchResponseCallback
      implements ChipClusters.ContentLauncherCluster.LaunchResponseCallback,
          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 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.AudioOutputClusterOutputInfo> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<ChipStructs.AudioOutputClusterOutputInfo>");
      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 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 DelegatedLauncherResponseCallback
      implements ChipClusters.ApplicationLauncherCluster.LauncherResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(Integer status, byte[] data) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo dataResponseValue = new CommandResponseInfo("data", "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 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 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 DelegatedGetSetupPINResponseCallback
      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 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 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 DelegatedTestSpecificResponseCallback
      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 DelegatedTestAddArgumentsResponseCallback
      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 DelegatedTestListInt8UReverseResponseCallback
      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 DelegatedTestEnumsResponseCallback
      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 DelegatedTestNullableOptionalResponseCallback
      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 DelegatedBooleanResponseCallback
      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 DelegatedSimpleStructResponseCallback
      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 DelegatedTestEmitTestEventResponseCallback
      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 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 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 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 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 basicClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BasicCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("basic", basicClusterInfo);
    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 bridgedDeviceBasicClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BridgedDeviceBasicCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("bridgedDeviceBasic", bridgedDeviceBasicClusterInfo);
    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 booleanStateClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BooleanStateCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("booleanState", booleanStateClusterInfo);
    ClusterInfo modeSelectClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ModeSelectCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("modeSelect", modeSelectClusterInfo);
    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);
    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("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("basic").combineCommands(source.get("basic"));
    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("bridgedDeviceBasic").combineCommands(source.get("bridgedDeviceBasic"));
    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("booleanState").combineCommands(source.get("booleanState"));
    destination.get("modeSelect").combineCommands(source.get("modeSelect"));
    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"));
  }

  @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 DelegatedAddGroupResponseCallback(),
            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 DelegatedViewGroupResponseCallback(),
            groupsviewGroupCommandParams);
    groupsClusterInteractionInfoMap.put("viewGroup", groupsviewGroupInteractionInfo);
    Map<String, CommandParameterInfo> groupsgetGroupMembershipCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupsgetGroupMembershipgroupListCommandParameterInfo =
        new CommandParameterInfo("groupList", ArrayList.class, Object.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 DelegatedGetGroupMembershipResponseCallback(),
            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 DelegatedRemoveGroupResponseCallback(),
            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 DelegatedAddSceneResponseCallback(),
            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 DelegatedViewSceneResponseCallback(),
            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 DelegatedRemoveSceneResponseCallback(),
            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 DelegatedRemoveAllScenesResponseCallback(),
            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 DelegatedStoreSceneResponseCallback(),
            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 DelegatedGetSceneMembershipResponseCallback(),
            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 onOffoffWithEffecteffectIdCommandParameterInfo =
        new CommandParameterInfo("effectId", Integer.class, Integer.class);
    onOffoffWithEffectCommandParams.put("effectId", onOffoffWithEffecteffectIdCommandParameterInfo);

    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("effectId"),
                      (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> 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> basicClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("basic", basicClusterInteractionInfoMap);
    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, Object.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 DelegatedQueryImageResponseCallback(),
            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 DelegatedApplyUpdateResponseCallback(),
            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 DelegatedArmFailSafeResponseCallback(),
            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 DelegatedSetRegulatoryConfigResponseCallback(),
            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 DelegatedCommissioningCompleteResponseCallback(),
            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 DelegatedScanNetworksResponseCallback(),
            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 DelegatedNetworkConfigResponseCallback(),
            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 DelegatedNetworkConfigResponseCallback(),
            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 DelegatedNetworkConfigResponseCallback(),
            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 DelegatedConnectNetworkResponseCallback(),
            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 DelegatedNetworkConfigResponseCallback(),
            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", byte[].class, byte[].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"),
                      (byte[]) commandArguments.get("transferFileDesignator"));
            },
            () -> new DelegatedRetrieveLogsResponseCallback(),
            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> bridgedDeviceBasicClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("bridgedDeviceBasic", bridgedDeviceBasicClusterInteractionInfoMap);
    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
        administratorCommissioningopenCommissioningWindowPAKEVerifierCommandParameterInfo =
            new CommandParameterInfo("PAKEVerifier", byte[].class, byte[].class);
    administratorCommissioningopenCommissioningWindowCommandParams.put(
        "PAKEVerifier",
        administratorCommissioningopenCommissioningWindowPAKEVerifierCommandParameterInfo);

    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("PAKEVerifier"),
                      (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 DelegatedAttestationResponseCallback(),
            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 DelegatedCertificateChainResponseCallback(),
            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 DelegatedCSRResponseCallback(),
            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 DelegatedNOCResponseCallback(),
            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 DelegatedNOCResponseCallback(),
            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 DelegatedNOCResponseCallback(),
            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 DelegatedNOCResponseCallback(),
            operationalCredentialsremoveFabricCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "removeFabric", operationalCredentialsremoveFabricInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsaddTrustedRootCertificateCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        operationalCredentialsaddTrustedRootCertificaterootCertificateCommandParameterInfo =
            new CommandParameterInfo("rootCertificate", byte[].class, byte[].class);
    operationalCredentialsaddTrustedRootCertificateCommandParams.put(
        "rootCertificate",
        operationalCredentialsaddTrustedRootCertificaterootCertificateCommandParameterInfo);

    InteractionInfo operationalCredentialsaddTrustedRootCertificateInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .addTrustedRootCertificate(
                      (DefaultClusterCallback) callback,
                      (byte[]) commandArguments.get("rootCertificate"));
            },
            () -> 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 DelegatedKeySetReadResponseCallback(),
            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, Object.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 DelegatedKeySetReadAllIndicesResponseCallback(),
            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> booleanStateClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("booleanState", booleanStateClusterInteractionInfoMap);
    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> 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 DelegatedGetWeekDayScheduleResponseCallback(),
            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 DelegatedGetYearDayScheduleResponseCallback(),
            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 DelegatedGetHolidayScheduleResponseCallback(),
            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 DelegatedGetUserResponseCallback(),
            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.DoorLockClusterDlCredential) commandArguments.get("credential"),
                      (byte[]) commandArguments.get("credentialData"),
                      (Integer) commandArguments.get("userIndex"),
                      (Integer) commandArguments.get("userStatus"),
                      (Integer) commandArguments.get("userType"),
                      10000);
            },
            () -> new DelegatedSetCredentialResponseCallback(),
            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.DoorLockClusterDlCredential) commandArguments.get("credential"));
            },
            () -> new DelegatedGetCredentialStatusResponseCallback(),
            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.DoorLockClusterDlCredential) 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 DelegatedGetWeeklyScheduleResponseCallback(),
            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 colorControlmoveToColorTemperaturecolorTemperatureCommandParameterInfo =
        new CommandParameterInfo("colorTemperature", Integer.class, Integer.class);
    colorControlmoveToColorTemperatureCommandParams.put(
        "colorTemperature", colorControlmoveToColorTemperaturecolorTemperatureCommandParameterInfo);

    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("colorTemperature"),
                      (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 DelegatedChangeChannelResponseCallback(),
            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 DelegatedNavigateTargetResponseCallback(),
            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 DelegatedPlaybackResponseCallback(),
            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 DelegatedPlaybackResponseCallback(),
            mediaPlaybackpauseCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("pause", mediaPlaybackpauseInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackstopPlaybackCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackstopPlaybackInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .stopPlayback(
                      (ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybackstopPlaybackCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put(
        "stopPlayback", mediaPlaybackstopPlaybackInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackstartOverCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackstartOverInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .startOver((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedPlaybackResponseCallback(),
            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 DelegatedPlaybackResponseCallback(),
            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 DelegatedPlaybackResponseCallback(),
            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 DelegatedPlaybackResponseCallback(),
            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 DelegatedPlaybackResponseCallback(),
            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 DelegatedPlaybackResponseCallback(),
            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 DelegatedPlaybackResponseCallback(),
            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 DelegatedPlaybackResponseCallback(),
            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 DelegatedSendKeyResponseCallback(),
            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.LaunchResponseCallback) callback,
                      (ChipStructs.ContentLauncherClusterContentSearch)
                          commandArguments.get("search"),
                      (Boolean) commandArguments.get("autoPlay"),
                      (Optional<String>) commandArguments.get("data"));
            },
            () -> new DelegatedLaunchResponseCallback(),
            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.LaunchResponseCallback) callback,
                      (String) commandArguments.get("contentURL"),
                      (Optional<String>) commandArguments.get("displayString"),
                      (Optional<ChipStructs.ContentLauncherClusterBrandingInformation>)
                          commandArguments.get("brandingInformation"));
            },
            () -> new DelegatedLaunchResponseCallback(),
            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,
                      (ChipStructs.ApplicationLauncherClusterApplication)
                          commandArguments.get("application"),
                      (Optional<byte[]>) commandArguments.get("data"));
            },
            () -> new DelegatedLauncherResponseCallback(),
            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,
                      (ChipStructs.ApplicationLauncherClusterApplication)
                          commandArguments.get("application"));
            },
            () -> new DelegatedLauncherResponseCallback(),
            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,
                      (ChipStructs.ApplicationLauncherClusterApplication)
                          commandArguments.get("application"));
            },
            () -> new DelegatedLauncherResponseCallback(),
            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 DelegatedGetSetupPINResponseCallback(),
            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 DelegatedTestSpecificResponseCallback(),
            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 DelegatedTestAddArgumentsResponseCallback(),
            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 DelegatedBooleanResponseCallback(),
            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 DelegatedBooleanResponseCallback(),
            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 DelegatedBooleanResponseCallback(),
            unitTestingtestListStructArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testListStructArgumentRequest", unitTestingtestListStructArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestListInt8UArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestListInt8UArgumentRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", ArrayList.class, Object.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 DelegatedBooleanResponseCallback(),
            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 DelegatedBooleanResponseCallback(),
            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 DelegatedBooleanResponseCallback(),
            unitTestingtestListNestedStructListArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testListNestedStructListArgumentRequest",
        unitTestingtestListNestedStructListArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestListInt8UReverseRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestListInt8UReverseRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", ArrayList.class, Object.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 DelegatedTestListInt8UReverseResponseCallback(),
            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 DelegatedTestEnumsResponseCallback(),
            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 DelegatedTestNullableOptionalResponseCallback(),
            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 DelegatedSimpleStructResponseCallback(),
            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 DelegatedTestEmitTestEventResponseCallback(),
            unitTestingtestEmitTestEventRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testEmitTestEventRequest", unitTestingtestEmitTestEventRequestInteractionInfo);
    commandMap.put("unitTesting", unitTestingClusterInteractionInfoMap);
    return commandMap;
  }
}
