/*
 *
 *    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 androidx.annotation.Nullable;
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;

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 DelegatedDescriptorClusterDeviceListAttributeCallback
      implements ChipClusters.DescriptorCluster.DeviceListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(List<ChipStructs.DescriptorClusterDeviceType> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<ChipStructs.DescriptorClusterDeviceType>");
      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 DelegatedBridgedActionsClusterActionListAttributeCallback
      implements ChipClusters.BridgedActionsCluster.ActionListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBridgedActionsClusterEndpointListAttributeCallback
      implements ChipClusters.BridgedActionsCluster.EndpointListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBridgedActionsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BridgedActionsCluster.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 DelegatedBridgedActionsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BridgedActionsCluster.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 DelegatedBridgedActionsClusterAttributeListAttributeCallback
      implements ChipClusters.BridgedActionsCluster.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.TestClusterCluster.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.TestClusterCluster.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.TestClusterCluster.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.TestClusterCluster.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.TestClusterCluster.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.TestClusterCluster.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.TestClusterCluster.SimpleStructResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(ChipStructs.TestClusterClusterSimpleStruct 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.TestClusterCluster.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 DelegatedTestClusterClusterListInt8uAttributeCallback
      implements ChipClusters.TestClusterCluster.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 DelegatedTestClusterClusterListOctetStringAttributeCallback
      implements ChipClusters.TestClusterCluster.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 DelegatedTestClusterClusterListStructOctetStringAttributeCallback
      implements ChipClusters.TestClusterCluster.ListStructOctetStringAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedTestClusterClusterListNullablesAndOptionalsStructAttributeCallback
      implements ChipClusters.TestClusterCluster.ListNullablesAndOptionalsStructAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedTestClusterClusterListLongOctetStringAttributeCallback
      implements ChipClusters.TestClusterCluster.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 DelegatedTestClusterClusterListFabricScopedAttributeCallback
      implements ChipClusters.TestClusterCluster.ListFabricScopedAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedTestClusterClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.TestClusterCluster.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 DelegatedTestClusterClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.TestClusterCluster.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 DelegatedTestClusterClusterAttributeListAttributeCallback
      implements ChipClusters.TestClusterCluster.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 bridgedActionsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BridgedActionsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("bridgedActions", bridgedActionsClusterInfo);
    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 testClusterClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.TestClusterCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("testCluster", testClusterClusterInfo);
    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("bridgedActions").combineCommands(source.get("bridgedActions"));
    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("testCluster").combineCommands(source.get("testCluster"));
  }

  @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> bridgedActionsClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> bridgedActionsinstantActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionsinstantActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionsinstantActionCommandParams.put(
        "actionID", bridgedActionsinstantActionactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsinstantActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionsinstantActionCommandParams.put(
        "invokeID", bridgedActionsinstantActioninvokeIDCommandParameterInfo);

    InteractionInfo bridgedActionsinstantActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .instantAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionsinstantActionCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "instantAction", bridgedActionsinstantActionInteractionInfo);
    Map<String, CommandParameterInfo> bridgedActionsinstantActionWithTransitionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionsinstantActionWithTransitionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionsinstantActionWithTransitionCommandParams.put(
        "actionID", bridgedActionsinstantActionWithTransitionactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsinstantActionWithTransitioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionsinstantActionWithTransitionCommandParams.put(
        "invokeID", bridgedActionsinstantActionWithTransitioninvokeIDCommandParameterInfo);

    CommandParameterInfo
        bridgedActionsinstantActionWithTransitiontransitionTimeCommandParameterInfo =
            new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    bridgedActionsinstantActionWithTransitionCommandParams.put(
        "transitionTime",
        bridgedActionsinstantActionWithTransitiontransitionTimeCommandParameterInfo);

    InteractionInfo bridgedActionsinstantActionWithTransitionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .instantActionWithTransition(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Integer) commandArguments.get("transitionTime"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionsinstantActionWithTransitionCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "instantActionWithTransition", bridgedActionsinstantActionWithTransitionInteractionInfo);
    Map<String, CommandParameterInfo> bridgedActionsstartActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionsstartActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionsstartActionCommandParams.put(
        "actionID", bridgedActionsstartActionactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsstartActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionsstartActionCommandParams.put(
        "invokeID", bridgedActionsstartActioninvokeIDCommandParameterInfo);

    InteractionInfo bridgedActionsstartActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .startAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionsstartActionCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "startAction", bridgedActionsstartActionInteractionInfo);
    Map<String, CommandParameterInfo> bridgedActionsstartActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionsstartActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionsstartActionWithDurationCommandParams.put(
        "actionID", bridgedActionsstartActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsstartActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionsstartActionWithDurationCommandParams.put(
        "invokeID", bridgedActionsstartActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsstartActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    bridgedActionsstartActionWithDurationCommandParams.put(
        "duration", bridgedActionsstartActionWithDurationdurationCommandParameterInfo);

    InteractionInfo bridgedActionsstartActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .startActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionsstartActionWithDurationCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "startActionWithDuration", bridgedActionsstartActionWithDurationInteractionInfo);
    Map<String, CommandParameterInfo> bridgedActionsstopActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionsstopActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionsstopActionCommandParams.put(
        "actionID", bridgedActionsstopActionactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsstopActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionsstopActionCommandParams.put(
        "invokeID", bridgedActionsstopActioninvokeIDCommandParameterInfo);

    InteractionInfo bridgedActionsstopActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .stopAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionsstopActionCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "stopAction", bridgedActionsstopActionInteractionInfo);
    Map<String, CommandParameterInfo> bridgedActionspauseActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionspauseActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionspauseActionCommandParams.put(
        "actionID", bridgedActionspauseActionactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionspauseActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionspauseActionCommandParams.put(
        "invokeID", bridgedActionspauseActioninvokeIDCommandParameterInfo);

    InteractionInfo bridgedActionspauseActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .pauseAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionspauseActionCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "pauseAction", bridgedActionspauseActionInteractionInfo);
    Map<String, CommandParameterInfo> bridgedActionspauseActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionspauseActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionspauseActionWithDurationCommandParams.put(
        "actionID", bridgedActionspauseActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionspauseActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionspauseActionWithDurationCommandParams.put(
        "invokeID", bridgedActionspauseActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo bridgedActionspauseActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    bridgedActionspauseActionWithDurationCommandParams.put(
        "duration", bridgedActionspauseActionWithDurationdurationCommandParameterInfo);

    InteractionInfo bridgedActionspauseActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .pauseActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionspauseActionWithDurationCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "pauseActionWithDuration", bridgedActionspauseActionWithDurationInteractionInfo);
    Map<String, CommandParameterInfo> bridgedActionsresumeActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionsresumeActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionsresumeActionCommandParams.put(
        "actionID", bridgedActionsresumeActionactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsresumeActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionsresumeActionCommandParams.put(
        "invokeID", bridgedActionsresumeActioninvokeIDCommandParameterInfo);

    InteractionInfo bridgedActionsresumeActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .resumeAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionsresumeActionCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "resumeAction", bridgedActionsresumeActionInteractionInfo);
    Map<String, CommandParameterInfo> bridgedActionsenableActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionsenableActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionsenableActionCommandParams.put(
        "actionID", bridgedActionsenableActionactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsenableActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionsenableActionCommandParams.put(
        "invokeID", bridgedActionsenableActioninvokeIDCommandParameterInfo);

    InteractionInfo bridgedActionsenableActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .enableAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionsenableActionCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "enableAction", bridgedActionsenableActionInteractionInfo);
    Map<String, CommandParameterInfo> bridgedActionsenableActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionsenableActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionsenableActionWithDurationCommandParams.put(
        "actionID", bridgedActionsenableActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsenableActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionsenableActionWithDurationCommandParams.put(
        "invokeID", bridgedActionsenableActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsenableActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    bridgedActionsenableActionWithDurationCommandParams.put(
        "duration", bridgedActionsenableActionWithDurationdurationCommandParameterInfo);

    InteractionInfo bridgedActionsenableActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .enableActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionsenableActionWithDurationCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "enableActionWithDuration", bridgedActionsenableActionWithDurationInteractionInfo);
    Map<String, CommandParameterInfo> bridgedActionsdisableActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionsdisableActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionsdisableActionCommandParams.put(
        "actionID", bridgedActionsdisableActionactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsdisableActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionsdisableActionCommandParams.put(
        "invokeID", bridgedActionsdisableActioninvokeIDCommandParameterInfo);

    InteractionInfo bridgedActionsdisableActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .disableAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionsdisableActionCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "disableAction", bridgedActionsdisableActionInteractionInfo);
    Map<String, CommandParameterInfo> bridgedActionsdisableActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo bridgedActionsdisableActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    bridgedActionsdisableActionWithDurationCommandParams.put(
        "actionID", bridgedActionsdisableActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsdisableActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    bridgedActionsdisableActionWithDurationCommandParams.put(
        "invokeID", bridgedActionsdisableActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo bridgedActionsdisableActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    bridgedActionsdisableActionWithDurationCommandParams.put(
        "duration", bridgedActionsdisableActionWithDurationdurationCommandParameterInfo);

    InteractionInfo bridgedActionsdisableActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BridgedActionsCluster) cluster)
                  .disableActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            bridgedActionsdisableActionWithDurationCommandParams);
    bridgedActionsClusterInteractionInfoMap.put(
        "disableActionWithDuration", bridgedActionsdisableActionWithDurationInteractionInfo);
    commandMap.put("bridgedActions", bridgedActionsClusterInteractionInfoMap);
    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> testClusterClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> testClustertestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo testClustertestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster).test((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            testClustertestCommandParams);
    testClusterClusterInteractionInfoMap.put("test", testClustertestInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestNotHandledCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo testClustertestNotHandledInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testNotHandled((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            testClustertestNotHandledCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testNotHandled", testClustertestNotHandledInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestSpecificCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo testClustertestSpecificInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testSpecific(
                      (ChipClusters.TestClusterCluster.TestSpecificResponseCallback) callback);
            },
            () -> new DelegatedTestSpecificResponseCallback(),
            testClustertestSpecificCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testSpecific", testClustertestSpecificInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestUnknownCommandCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo testClustertestUnknownCommandInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testUnknownCommand((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            testClustertestUnknownCommandCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testUnknownCommand", testClustertestUnknownCommandInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestAddArgumentsCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo testClustertestAddArgumentsarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Integer.class, Integer.class);
    testClustertestAddArgumentsCommandParams.put(
        "arg1", testClustertestAddArgumentsarg1CommandParameterInfo);

    CommandParameterInfo testClustertestAddArgumentsarg2CommandParameterInfo =
        new CommandParameterInfo("arg2", Integer.class, Integer.class);
    testClustertestAddArgumentsCommandParams.put(
        "arg2", testClustertestAddArgumentsarg2CommandParameterInfo);

    InteractionInfo testClustertestAddArgumentsInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testAddArguments(
                      (ChipClusters.TestClusterCluster.TestAddArgumentsResponseCallback) callback,
                      (Integer) commandArguments.get("arg1"),
                      (Integer) commandArguments.get("arg2"));
            },
            () -> new DelegatedTestAddArgumentsResponseCallback(),
            testClustertestAddArgumentsCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testAddArguments", testClustertestAddArgumentsInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestStructArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo testClustertestStructArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testStructArgumentRequest(
                      (ChipClusters.TestClusterCluster.BooleanResponseCallback) callback,
                      (ChipStructs.TestClusterClusterSimpleStruct) commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            testClustertestStructArgumentRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testStructArgumentRequest", testClustertestStructArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestNestedStructArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo testClustertestNestedStructArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testNestedStructArgumentRequest(
                      (ChipClusters.TestClusterCluster.BooleanResponseCallback) callback,
                      (ChipStructs.TestClusterClusterNestedStruct) commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            testClustertestNestedStructArgumentRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testNestedStructArgumentRequest",
        testClustertestNestedStructArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestListStructArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo testClustertestListStructArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testListStructArgumentRequest(
                      (ChipClusters.TestClusterCluster.BooleanResponseCallback) callback,
                      (ArrayList<ChipStructs.TestClusterClusterSimpleStruct>)
                          commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            testClustertestListStructArgumentRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testListStructArgumentRequest", testClustertestListStructArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestListInt8UArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo testClustertestListInt8UArgumentRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", ArrayList.class, Object.class);
    testClustertestListInt8UArgumentRequestCommandParams.put(
        "arg1", testClustertestListInt8UArgumentRequestarg1CommandParameterInfo);

    InteractionInfo testClustertestListInt8UArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testListInt8UArgumentRequest(
                      (ChipClusters.TestClusterCluster.BooleanResponseCallback) callback,
                      (ArrayList<Integer>) commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            testClustertestListInt8UArgumentRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testListInt8UArgumentRequest", testClustertestListInt8UArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestNestedStructListArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo testClustertestNestedStructListArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testNestedStructListArgumentRequest(
                      (ChipClusters.TestClusterCluster.BooleanResponseCallback) callback,
                      (ChipStructs.TestClusterClusterNestedStructList)
                          commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            testClustertestNestedStructListArgumentRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testNestedStructListArgumentRequest",
        testClustertestNestedStructListArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo>
        testClustertestListNestedStructListArgumentRequestCommandParams =
            new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo testClustertestListNestedStructListArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testListNestedStructListArgumentRequest(
                      (ChipClusters.TestClusterCluster.BooleanResponseCallback) callback,
                      (ArrayList<ChipStructs.TestClusterClusterNestedStructList>)
                          commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            testClustertestListNestedStructListArgumentRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testListNestedStructListArgumentRequest",
        testClustertestListNestedStructListArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestListInt8UReverseRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo testClustertestListInt8UReverseRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", ArrayList.class, Object.class);
    testClustertestListInt8UReverseRequestCommandParams.put(
        "arg1", testClustertestListInt8UReverseRequestarg1CommandParameterInfo);

    InteractionInfo testClustertestListInt8UReverseRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testListInt8UReverseRequest(
                      (ChipClusters.TestClusterCluster.TestListInt8UReverseResponseCallback)
                          callback,
                      (ArrayList<Integer>) commandArguments.get("arg1"));
            },
            () -> new DelegatedTestListInt8UReverseResponseCallback(),
            testClustertestListInt8UReverseRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testListInt8UReverseRequest", testClustertestListInt8UReverseRequestInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestEnumsRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo testClustertestEnumsRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Integer.class, Integer.class);
    testClustertestEnumsRequestCommandParams.put(
        "arg1", testClustertestEnumsRequestarg1CommandParameterInfo);

    CommandParameterInfo testClustertestEnumsRequestarg2CommandParameterInfo =
        new CommandParameterInfo("arg2", Integer.class, Integer.class);
    testClustertestEnumsRequestCommandParams.put(
        "arg2", testClustertestEnumsRequestarg2CommandParameterInfo);

    InteractionInfo testClustertestEnumsRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testEnumsRequest(
                      (ChipClusters.TestClusterCluster.TestEnumsResponseCallback) callback,
                      (Integer) commandArguments.get("arg1"),
                      (Integer) commandArguments.get("arg2"));
            },
            () -> new DelegatedTestEnumsResponseCallback(),
            testClustertestEnumsRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testEnumsRequest", testClustertestEnumsRequestInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestNullableOptionalRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo testClustertestNullableOptionalRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Optional.class, Integer.class);
    testClustertestNullableOptionalRequestCommandParams.put(
        "arg1", testClustertestNullableOptionalRequestarg1CommandParameterInfo);

    InteractionInfo testClustertestNullableOptionalRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testNullableOptionalRequest(
                      (ChipClusters.TestClusterCluster.TestNullableOptionalResponseCallback)
                          callback,
                      (Optional<Integer>) commandArguments.get("arg1"));
            },
            () -> new DelegatedTestNullableOptionalResponseCallback(),
            testClustertestNullableOptionalRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testNullableOptionalRequest", testClustertestNullableOptionalRequestInteractionInfo);
    Map<String, CommandParameterInfo> testClustersimpleStructEchoRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo testClustersimpleStructEchoRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .simpleStructEchoRequest(
                      (ChipClusters.TestClusterCluster.SimpleStructResponseCallback) callback,
                      (ChipStructs.TestClusterClusterSimpleStruct) commandArguments.get("arg1"));
            },
            () -> new DelegatedSimpleStructResponseCallback(),
            testClustersimpleStructEchoRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "simpleStructEchoRequest", testClustersimpleStructEchoRequestInteractionInfo);
    Map<String, CommandParameterInfo> testClustertimedInvokeRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo testClustertimedInvokeRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .timedInvokeRequest((DefaultClusterCallback) callback, 10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            testClustertimedInvokeRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "timedInvokeRequest", testClustertimedInvokeRequestInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestSimpleOptionalArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo testClustertestSimpleOptionalArgumentRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Optional.class, Boolean.class);
    testClustertestSimpleOptionalArgumentRequestCommandParams.put(
        "arg1", testClustertestSimpleOptionalArgumentRequestarg1CommandParameterInfo);

    InteractionInfo testClustertestSimpleOptionalArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testSimpleOptionalArgumentRequest(
                      (DefaultClusterCallback) callback,
                      (Optional<Boolean>) commandArguments.get("arg1"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            testClustertestSimpleOptionalArgumentRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testSimpleOptionalArgumentRequest",
        testClustertestSimpleOptionalArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> testClustertestEmitTestEventRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo testClustertestEmitTestEventRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Integer.class, Integer.class);
    testClustertestEmitTestEventRequestCommandParams.put(
        "arg1", testClustertestEmitTestEventRequestarg1CommandParameterInfo);

    CommandParameterInfo testClustertestEmitTestEventRequestarg2CommandParameterInfo =
        new CommandParameterInfo("arg2", Integer.class, Integer.class);
    testClustertestEmitTestEventRequestCommandParams.put(
        "arg2", testClustertestEmitTestEventRequestarg2CommandParameterInfo);

    CommandParameterInfo testClustertestEmitTestEventRequestarg3CommandParameterInfo =
        new CommandParameterInfo("arg3", Boolean.class, Boolean.class);
    testClustertestEmitTestEventRequestCommandParams.put(
        "arg3", testClustertestEmitTestEventRequestarg3CommandParameterInfo);

    InteractionInfo testClustertestEmitTestEventRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TestClusterCluster) cluster)
                  .testEmitTestEventRequest(
                      (ChipClusters.TestClusterCluster.TestEmitTestEventResponseCallback) callback,
                      (Integer) commandArguments.get("arg1"),
                      (Integer) commandArguments.get("arg2"),
                      (Boolean) commandArguments.get("arg3"));
            },
            () -> new DelegatedTestEmitTestEventResponseCallback(),
            testClustertestEmitTestEventRequestCommandParams);
    testClusterClusterInteractionInfoMap.put(
        "testEmitTestEventRequest", testClustertestEmitTestEventRequestInteractionInfo);
    commandMap.put("testCluster", testClusterClusterInteractionInfoMap);
    return commandMap;
  }
}
