/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

// THIS FILE IS GENERATED BY ZAP

package chip.devicecontroller;

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

public class ClusterInfoMapping {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    @Override
    public void onSuccess(Integer status, byte[] content, Long timeStamp, Long timeSinceBoot) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo contentResponseValue = new CommandResponseInfo("content", "byte[]");
      responseValues.put(contentResponseValue, content);
      CommandResponseInfo timeStampResponseValue = new CommandResponseInfo("timeStamp", "Long");
      responseValues.put(timeStampResponseValue, timeStamp);
      CommandResponseInfo timeSinceBootResponseValue =
          new CommandResponseInfo("timeSinceBoot", "Long");
      responseValues.put(timeSinceBootResponseValue, timeSinceBoot);
      callback.onSuccess(responseValues);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  public static class DelegatedThreadNetworkDiagnosticsClusterNeighborTableListAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.NeighborTableListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedThreadNetworkDiagnosticsClusterRouteTableListAttributeCallback
      implements ChipClusters.ThreadNetworkDiagnosticsCluster.RouteTableListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  public static class DelegatedWiFiNetworkDiagnosticsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedWiFiNetworkDiagnosticsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedWiFiNetworkDiagnosticsClusterAttributeListAttributeCallback
      implements ChipClusters.WiFiNetworkDiagnosticsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static
  class DelegatedEthernetNetworkDiagnosticsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.EthernetNetworkDiagnosticsCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedEthernetNetworkDiagnosticsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.EthernetNetworkDiagnosticsCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedEthernetNetworkDiagnosticsClusterAttributeListAttributeCallback
      implements ChipClusters.EthernetNetworkDiagnosticsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBridgedDeviceBasicClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BridgedDeviceBasicCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBridgedDeviceBasicClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BridgedDeviceBasicCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBridgedDeviceBasicClusterAttributeListAttributeCallback
      implements ChipClusters.BridgedDeviceBasicCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedSwitchClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.SwitchCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedSwitchClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.SwitchCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedSwitchClusterAttributeListAttributeCallback
      implements ChipClusters.SwitchCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static
  class DelegatedAdministratorCommissioningClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.AdministratorCommissioningCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedAdministratorCommissioningClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.AdministratorCommissioningCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedAdministratorCommissioningClusterAttributeListAttributeCallback
      implements ChipClusters.AdministratorCommissioningCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedAttestationResponseCallback
      implements ChipClusters.OperationalCredentialsCluster.AttestationResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedCertificateChainResponseCallback
      implements ChipClusters.OperationalCredentialsCluster.CertificateChainResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedCSRResponseCallback
      implements ChipClusters.OperationalCredentialsCluster.CSRResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedNOCResponseCallback
      implements ChipClusters.OperationalCredentialsCluster.NOCResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedOperationalCredentialsClusterNOCsAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster.NOCsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedOperationalCredentialsClusterFabricsAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster.FabricsAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedOperationalCredentialsClusterTrustedRootCertificatesAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster
              .TrustedRootCertificatesAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedOperationalCredentialsClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedOperationalCredentialsClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedOperationalCredentialsClusterAttributeListAttributeCallback
      implements ChipClusters.OperationalCredentialsCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedKeySetReadResponseCallback
      implements ChipClusters.GroupKeyManagementCluster.KeySetReadResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(ChipStructs.GroupKeyManagementClusterGroupKeySetStruct GroupKeySet) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      // GroupKeySet: Struct GroupKeySetStruct
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

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

  public static class DelegatedKeySetReadAllIndicesResponseCallback
      implements ChipClusters.GroupKeyManagementCluster.KeySetReadAllIndicesResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedGroupKeyManagementClusterGroupKeyMapAttributeCallback
      implements ChipClusters.GroupKeyManagementCluster.GroupKeyMapAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedGroupKeyManagementClusterGroupTableAttributeCallback
      implements ChipClusters.GroupKeyManagementCluster.GroupTableAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedGroupKeyManagementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.GroupKeyManagementCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedGroupKeyManagementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.GroupKeyManagementCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedGroupKeyManagementClusterAttributeListAttributeCallback
      implements ChipClusters.GroupKeyManagementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedFixedLabelClusterLabelListAttributeCallback
      implements ChipClusters.FixedLabelCluster.LabelListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedFixedLabelClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.FixedLabelCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedFixedLabelClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.FixedLabelCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedFixedLabelClusterAttributeListAttributeCallback
      implements ChipClusters.FixedLabelCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedUserLabelClusterLabelListAttributeCallback
      implements ChipClusters.UserLabelCluster.LabelListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedUserLabelClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.UserLabelCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedUserLabelClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.UserLabelCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBooleanStateClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BooleanStateCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBooleanStateClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BooleanStateCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBooleanStateClusterAttributeListAttributeCallback
      implements ChipClusters.BooleanStateCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedModeSelectClusterSupportedModesAttributeCallback
      implements ChipClusters.ModeSelectCluster.SupportedModesAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedModeSelectClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ModeSelectCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedModeSelectClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ModeSelectCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedModeSelectClusterAttributeListAttributeCallback
      implements ChipClusters.ModeSelectCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedGetWeekDayScheduleResponseCallback
      implements ChipClusters.DoorLockCluster.GetWeekDayScheduleResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(
        Integer weekDayIndex,
        Integer userIndex,
        Integer status,
        Optional<Integer> daysMask,
        Optional<Integer> startHour,
        Optional<Integer> startMinute,
        Optional<Integer> endHour,
        Optional<Integer> endMinute) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo weekDayIndexResponseValue =
          new CommandResponseInfo("weekDayIndex", "Integer");
      responseValues.put(weekDayIndexResponseValue, weekDayIndex);
      CommandResponseInfo userIndexResponseValue = new CommandResponseInfo("userIndex", "Integer");
      responseValues.put(userIndexResponseValue, userIndex);
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo daysMaskResponseValue =
          new CommandResponseInfo("daysMask", "Optional<Integer>");
      responseValues.put(daysMaskResponseValue, daysMask);
      CommandResponseInfo startHourResponseValue =
          new CommandResponseInfo("startHour", "Optional<Integer>");
      responseValues.put(startHourResponseValue, startHour);
      CommandResponseInfo startMinuteResponseValue =
          new CommandResponseInfo("startMinute", "Optional<Integer>");
      responseValues.put(startMinuteResponseValue, startMinute);
      CommandResponseInfo endHourResponseValue =
          new CommandResponseInfo("endHour", "Optional<Integer>");
      responseValues.put(endHourResponseValue, endHour);
      CommandResponseInfo endMinuteResponseValue =
          new CommandResponseInfo("endMinute", "Optional<Integer>");
      responseValues.put(endMinuteResponseValue, endMinute);
      callback.onSuccess(responseValues);
    }

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

  public static class DelegatedGetYearDayScheduleResponseCallback
      implements ChipClusters.DoorLockCluster.GetYearDayScheduleResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(
        Integer yearDayIndex,
        Integer userIndex,
        Integer status,
        Optional<Long> localStartTime,
        Optional<Long> localEndTime) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo yearDayIndexResponseValue =
          new CommandResponseInfo("yearDayIndex", "Integer");
      responseValues.put(yearDayIndexResponseValue, yearDayIndex);
      CommandResponseInfo userIndexResponseValue = new CommandResponseInfo("userIndex", "Integer");
      responseValues.put(userIndexResponseValue, userIndex);
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo localStartTimeResponseValue =
          new CommandResponseInfo("localStartTime", "Optional<Long>");
      responseValues.put(localStartTimeResponseValue, localStartTime);
      CommandResponseInfo localEndTimeResponseValue =
          new CommandResponseInfo("localEndTime", "Optional<Long>");
      responseValues.put(localEndTimeResponseValue, localEndTime);
      callback.onSuccess(responseValues);
    }

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

  public static class DelegatedGetHolidayScheduleResponseCallback
      implements ChipClusters.DoorLockCluster.GetHolidayScheduleResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(
        Integer holidayIndex,
        Integer status,
        Optional<Long> localStartTime,
        Optional<Long> localEndTime,
        Optional<Integer> operatingMode) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo holidayIndexResponseValue =
          new CommandResponseInfo("holidayIndex", "Integer");
      responseValues.put(holidayIndexResponseValue, holidayIndex);
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo localStartTimeResponseValue =
          new CommandResponseInfo("localStartTime", "Optional<Long>");
      responseValues.put(localStartTimeResponseValue, localStartTime);
      CommandResponseInfo localEndTimeResponseValue =
          new CommandResponseInfo("localEndTime", "Optional<Long>");
      responseValues.put(localEndTimeResponseValue, localEndTime);
      CommandResponseInfo operatingModeResponseValue =
          new CommandResponseInfo("operatingMode", "Optional<Integer>");
      responseValues.put(operatingModeResponseValue, operatingMode);
      callback.onSuccess(responseValues);
    }

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

  public static class DelegatedGetUserResponseCallback
      implements ChipClusters.DoorLockCluster.GetUserResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(
        Integer userIndex,
        @Nullable String userName,
        @Nullable Long userUniqueId,
        @Nullable Integer userStatus,
        @Nullable Integer userType,
        @Nullable Integer credentialRule,
        @Nullable ArrayList<ChipStructs.DoorLockClusterDlCredential> credentials,
        @Nullable Integer creatorFabricIndex,
        @Nullable Integer lastModifiedFabricIndex,
        @Nullable Integer nextUserIndex) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo userIndexResponseValue = new CommandResponseInfo("userIndex", "Integer");
      responseValues.put(userIndexResponseValue, userIndex);
      CommandResponseInfo userNameResponseValue = new CommandResponseInfo("userName", "String");
      responseValues.put(userNameResponseValue, userName);
      CommandResponseInfo userUniqueIdResponseValue =
          new CommandResponseInfo("userUniqueId", "Long");
      responseValues.put(userUniqueIdResponseValue, userUniqueId);
      CommandResponseInfo userStatusResponseValue =
          new CommandResponseInfo("userStatus", "Integer");
      responseValues.put(userStatusResponseValue, userStatus);
      CommandResponseInfo userTypeResponseValue = new CommandResponseInfo("userType", "Integer");
      responseValues.put(userTypeResponseValue, userType);
      CommandResponseInfo credentialRuleResponseValue =
          new CommandResponseInfo("credentialRule", "Integer");
      responseValues.put(credentialRuleResponseValue, credentialRule);
      // credentials: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      CommandResponseInfo creatorFabricIndexResponseValue =
          new CommandResponseInfo("creatorFabricIndex", "Integer");
      responseValues.put(creatorFabricIndexResponseValue, creatorFabricIndex);
      CommandResponseInfo lastModifiedFabricIndexResponseValue =
          new CommandResponseInfo("lastModifiedFabricIndex", "Integer");
      responseValues.put(lastModifiedFabricIndexResponseValue, lastModifiedFabricIndex);
      CommandResponseInfo nextUserIndexResponseValue =
          new CommandResponseInfo("nextUserIndex", "Integer");
      responseValues.put(nextUserIndexResponseValue, nextUserIndex);
      callback.onSuccess(responseValues);
    }

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

  public static class DelegatedSetCredentialResponseCallback
      implements ChipClusters.DoorLockCluster.SetCredentialResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(
        Integer status, @Nullable Integer userIndex, @Nullable Integer nextCredentialIndex) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo userIndexResponseValue = new CommandResponseInfo("userIndex", "Integer");
      responseValues.put(userIndexResponseValue, userIndex);
      CommandResponseInfo nextCredentialIndexResponseValue =
          new CommandResponseInfo("nextCredentialIndex", "Integer");
      responseValues.put(nextCredentialIndexResponseValue, nextCredentialIndex);
      callback.onSuccess(responseValues);
    }

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

  public static class DelegatedGetCredentialStatusResponseCallback
      implements ChipClusters.DoorLockCluster.GetCredentialStatusResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(
        Boolean credentialExists,
        @Nullable Integer userIndex,
        @Nullable Integer creatorFabricIndex,
        @Nullable Integer lastModifiedFabricIndex,
        @Nullable Integer nextCredentialIndex) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo credentialExistsResponseValue =
          new CommandResponseInfo("credentialExists", "Boolean");
      responseValues.put(credentialExistsResponseValue, credentialExists);
      CommandResponseInfo userIndexResponseValue = new CommandResponseInfo("userIndex", "Integer");
      responseValues.put(userIndexResponseValue, userIndex);
      CommandResponseInfo creatorFabricIndexResponseValue =
          new CommandResponseInfo("creatorFabricIndex", "Integer");
      responseValues.put(creatorFabricIndexResponseValue, creatorFabricIndex);
      CommandResponseInfo lastModifiedFabricIndexResponseValue =
          new CommandResponseInfo("lastModifiedFabricIndex", "Integer");
      responseValues.put(lastModifiedFabricIndexResponseValue, lastModifiedFabricIndex);
      CommandResponseInfo nextCredentialIndexResponseValue =
          new CommandResponseInfo("nextCredentialIndex", "Integer");
      responseValues.put(nextCredentialIndexResponseValue, nextCredentialIndex);
      callback.onSuccess(responseValues);
    }

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

  public static class DelegatedDoorLockClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.DoorLockCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedDoorLockClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.DoorLockCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedDoorLockClusterAttributeListAttributeCallback
      implements ChipClusters.DoorLockCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedWindowCoveringClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.WindowCoveringCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedWindowCoveringClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.WindowCoveringCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedWindowCoveringClusterAttributeListAttributeCallback
      implements ChipClusters.WindowCoveringCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBarrierControlClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BarrierControlCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBarrierControlClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BarrierControlCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBarrierControlClusterAttributeListAttributeCallback
      implements ChipClusters.BarrierControlCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static
  class DelegatedPumpConfigurationAndControlClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static
  class DelegatedPumpConfigurationAndControlClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedPumpConfigurationAndControlClusterAttributeListAttributeCallback
      implements ChipClusters.PumpConfigurationAndControlCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedGetWeeklyScheduleResponseCallback
      implements ChipClusters.ThermostatCluster.GetWeeklyScheduleResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(
        Integer NumberOfTransitionsForSequence,
        Integer DayOfWeekForSequence,
        Integer ModeForSequence,
        ArrayList<ChipStructs.ThermostatClusterThermostatScheduleTransition> Transitions) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo NumberOfTransitionsForSequenceResponseValue =
          new CommandResponseInfo("NumberOfTransitionsForSequence", "Integer");
      responseValues.put(
          NumberOfTransitionsForSequenceResponseValue, NumberOfTransitionsForSequence);
      CommandResponseInfo DayOfWeekForSequenceResponseValue =
          new CommandResponseInfo("DayOfWeekForSequence", "Integer");
      responseValues.put(DayOfWeekForSequenceResponseValue, DayOfWeekForSequence);
      CommandResponseInfo ModeForSequenceResponseValue =
          new CommandResponseInfo("ModeForSequence", "Integer");
      responseValues.put(ModeForSequenceResponseValue, ModeForSequence);
      // Transitions: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

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

  public static class DelegatedThermostatClusterAttributeListAttributeCallback
      implements ChipClusters.ThermostatCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedFanControlClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.FanControlCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedFanControlClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.FanControlCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedFanControlClusterAttributeListAttributeCallback
      implements ChipClusters.FanControlCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static
  class DelegatedThermostatUserInterfaceConfigurationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ThermostatUserInterfaceConfigurationCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static
  class DelegatedThermostatUserInterfaceConfigurationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ThermostatUserInterfaceConfigurationCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static
  class DelegatedThermostatUserInterfaceConfigurationClusterAttributeListAttributeCallback
      implements ChipClusters.ThermostatUserInterfaceConfigurationCluster
              .AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedColorControlClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ColorControlCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedColorControlClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ColorControlCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedColorControlClusterAttributeListAttributeCallback
      implements ChipClusters.ColorControlCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBallastConfigurationClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBallastConfigurationClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedBallastConfigurationClusterAttributeListAttributeCallback
      implements ChipClusters.BallastConfigurationCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedIlluminanceMeasurementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.IlluminanceMeasurementCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedIlluminanceMeasurementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.IlluminanceMeasurementCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedIlluminanceMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.IlluminanceMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedTemperatureMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.TemperatureMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedPressureMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.PressureMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedFlowMeasurementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.FlowMeasurementCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedFlowMeasurementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.FlowMeasurementCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedFlowMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.FlowMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static
  class DelegatedRelativeHumidityMeasurementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.RelativeHumidityMeasurementCluster
              .GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static
  class DelegatedRelativeHumidityMeasurementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.RelativeHumidityMeasurementCluster
              .AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedRelativeHumidityMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.RelativeHumidityMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedOccupancySensingClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.OccupancySensingCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedOccupancySensingClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.OccupancySensingCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedOccupancySensingClusterAttributeListAttributeCallback
      implements ChipClusters.OccupancySensingCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedWakeOnLanClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.WakeOnLanCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedWakeOnLanClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.WakeOnLanCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedWakeOnLanClusterAttributeListAttributeCallback
      implements ChipClusters.WakeOnLanCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedChangeChannelResponseCallback
      implements ChipClusters.ChannelCluster.ChangeChannelResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(Integer status, Optional<String> data) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo dataResponseValue = new CommandResponseInfo("data", "Optional<String>");
      responseValues.put(dataResponseValue, data);
      callback.onSuccess(responseValues);
    }

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

  public static class DelegatedChannelClusterChannelListAttributeCallback
      implements ChipClusters.ChannelCluster.ChannelListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedChannelClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ChannelCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedChannelClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ChannelCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedChannelClusterAttributeListAttributeCallback
      implements ChipClusters.ChannelCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedNavigateTargetResponseCallback
      implements ChipClusters.TargetNavigatorCluster.NavigateTargetResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(Integer status, Optional<String> data) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo dataResponseValue = new CommandResponseInfo("data", "Optional<String>");
      responseValues.put(dataResponseValue, data);
      callback.onSuccess(responseValues);
    }

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

  public static class DelegatedTargetNavigatorClusterTargetListAttributeCallback
      implements ChipClusters.TargetNavigatorCluster.TargetListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedTargetNavigatorClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.TargetNavigatorCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedTargetNavigatorClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.TargetNavigatorCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedTargetNavigatorClusterAttributeListAttributeCallback
      implements ChipClusters.TargetNavigatorCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedPlaybackResponseCallback
      implements ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

    @Override
    public void onSuccess(Integer status, Optional<String> data) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo dataResponseValue = new CommandResponseInfo("data", "Optional<String>");
      responseValues.put(dataResponseValue, data);
      callback.onSuccess(responseValues);
    }

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

  public static class DelegatedMediaPlaybackClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.MediaPlaybackCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedMediaPlaybackClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.MediaPlaybackCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedMediaPlaybackClusterAttributeListAttributeCallback
      implements ChipClusters.MediaPlaybackCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedMediaInputClusterInputListAttributeCallback
      implements ChipClusters.MediaInputCluster.InputListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedMediaInputClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.MediaInputCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedMediaInputClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.MediaInputCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedMediaInputClusterAttributeListAttributeCallback
      implements ChipClusters.MediaInputCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

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

  public static class DelegatedLowPowerClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.LowPowerCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

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

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

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLowPowerClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.LowPowerCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLowPowerClusterAttributeListAttributeCallback
      implements ChipClusters.LowPowerCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedSendKeyResponseCallback
      implements ChipClusters.KeypadInputCluster.SendKeyResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer status) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedKeypadInputClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.KeypadInputCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedKeypadInputClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.KeypadInputCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedKeypadInputClusterAttributeListAttributeCallback
      implements ChipClusters.KeypadInputCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLaunchResponseCallback
      implements ChipClusters.ContentLauncherCluster.LaunchResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer status, Optional<String> data) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo dataResponseValue = new CommandResponseInfo("data", "Optional<String>");
      responseValues.put(dataResponseValue, data);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedContentLauncherClusterAcceptHeaderAttributeCallback
      implements ChipClusters.ContentLauncherCluster.AcceptHeaderAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<String> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<String>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedContentLauncherClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ContentLauncherCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedContentLauncherClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ContentLauncherCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedContentLauncherClusterAttributeListAttributeCallback
      implements ChipClusters.ContentLauncherCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAudioOutputClusterOutputListAttributeCallback
      implements ChipClusters.AudioOutputCluster.OutputListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.AudioOutputClusterOutputInfo> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<ChipStructs.AudioOutputClusterOutputInfo>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAudioOutputClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.AudioOutputCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAudioOutputClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.AudioOutputCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAudioOutputClusterAttributeListAttributeCallback
      implements ChipClusters.AudioOutputCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedLauncherResponseCallback
      implements ChipClusters.ApplicationLauncherCluster.LauncherResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer status, byte[] data) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer");
      responseValues.put(statusResponseValue, status);
      CommandResponseInfo dataResponseValue = new CommandResponseInfo("data", "byte[]");
      responseValues.put(dataResponseValue, data);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedApplicationLauncherClusterCatalogListAttributeCallback
      implements ChipClusters.ApplicationLauncherCluster.CatalogListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationLauncherClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ApplicationLauncherCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationLauncherClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ApplicationLauncherCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationLauncherClusterAttributeListAttributeCallback
      implements ChipClusters.ApplicationLauncherCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationBasicClusterAllowedVendorListAttributeCallback
      implements ChipClusters.ApplicationBasicCluster.AllowedVendorListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationBasicClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ApplicationBasicCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationBasicClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ApplicationBasicCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedApplicationBasicClusterAttributeListAttributeCallback
      implements ChipClusters.ApplicationBasicCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedGetSetupPINResponseCallback
      implements ChipClusters.AccountLoginCluster.GetSetupPINResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(String setupPIN) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("setupPIN", "String");
      responseValues.put(setupPINResponseValue, setupPIN);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedAccountLoginClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.AccountLoginCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccountLoginClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.AccountLoginCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedAccountLoginClusterAttributeListAttributeCallback
      implements ChipClusters.AccountLoginCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedElectricalMeasurementClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.ElectricalMeasurementCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedElectricalMeasurementClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.ElectricalMeasurementCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedElectricalMeasurementClusterAttributeListAttributeCallback
      implements ChipClusters.ElectricalMeasurementCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedTestSpecificResponseCallback
      implements ChipClusters.UnitTestingCluster.TestSpecificResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer returnValue) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo returnValueResponseValue =
          new CommandResponseInfo("returnValue", "Integer");
      responseValues.put(returnValueResponseValue, returnValue);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedTestAddArgumentsResponseCallback
      implements ChipClusters.UnitTestingCluster.TestAddArgumentsResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer returnValue) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo returnValueResponseValue =
          new CommandResponseInfo("returnValue", "Integer");
      responseValues.put(returnValueResponseValue, returnValue);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedTestListInt8UReverseResponseCallback
      implements ChipClusters.UnitTestingCluster.TestListInt8UReverseResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(ArrayList<Integer> arg1) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      // arg1: /* TYPE WARNING: array array defaults to */ uint8_t *
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedTestEnumsResponseCallback
      implements ChipClusters.UnitTestingCluster.TestEnumsResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Integer arg1, Integer arg2) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo arg1ResponseValue = new CommandResponseInfo("arg1", "Integer");
      responseValues.put(arg1ResponseValue, arg1);
      CommandResponseInfo arg2ResponseValue = new CommandResponseInfo("arg2", "Integer");
      responseValues.put(arg2ResponseValue, arg2);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedTestNullableOptionalResponseCallback
      implements ChipClusters.UnitTestingCluster.TestNullableOptionalResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        Boolean wasPresent,
        Optional<Boolean> wasNull,
        Optional<Integer> value,
        @Nullable Optional<Integer> originalValue) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo wasPresentResponseValue =
          new CommandResponseInfo("wasPresent", "Boolean");
      responseValues.put(wasPresentResponseValue, wasPresent);
      CommandResponseInfo wasNullResponseValue =
          new CommandResponseInfo("wasNull", "Optional<Boolean>");
      responseValues.put(wasNullResponseValue, wasNull);
      CommandResponseInfo valueResponseValue =
          new CommandResponseInfo("value", "Optional<Integer>");
      responseValues.put(valueResponseValue, value);
      CommandResponseInfo originalValueResponseValue =
          new CommandResponseInfo("originalValue", "Optional<Integer>");
      responseValues.put(originalValueResponseValue, originalValue);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedBooleanResponseCallback
      implements ChipClusters.UnitTestingCluster.BooleanResponseCallback, DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Boolean value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo valueResponseValue = new CommandResponseInfo("value", "Boolean");
      responseValues.put(valueResponseValue, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedSimpleStructResponseCallback
      implements ChipClusters.UnitTestingCluster.SimpleStructResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(ChipStructs.UnitTestingClusterSimpleStruct arg1) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      // arg1: Struct SimpleStruct
      // Conversion from this type to Java is not properly implemented yet
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedTestEmitTestEventResponseCallback
      implements ChipClusters.UnitTestingCluster.TestEmitTestEventResponseCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(Long value) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo valueResponseValue = new CommandResponseInfo("value", "Long");
      responseValues.put(valueResponseValue, value);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception error) {
      callback.onFailure(error);
    }
  }

  public static class DelegatedUnitTestingClusterListInt8uAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListInt8uAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Integer> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<Integer>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterListOctetStringAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListOctetStringAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<byte[]> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<byte[]>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterListStructOctetStringAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListStructOctetStringAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.UnitTestingClusterTestListStructOctet> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.UnitTestingClusterTestListStructOctet>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterListNullablesAndOptionalsStructAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListNullablesAndOptionalsStructAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(
        List<ChipStructs.UnitTestingClusterNullablesAndOptionalsStruct> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.UnitTestingClusterNullablesAndOptionalsStruct>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterListLongOctetStringAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListLongOctetStringAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<byte[]> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo("valueList", "List<byte[]>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterListFabricScopedAttributeCallback
      implements ChipClusters.UnitTestingCluster.ListFabricScopedAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<ChipStructs.UnitTestingClusterTestFabricScoped> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo =
          new CommandResponseInfo(
              "valueList", "List<ChipStructs.UnitTestingClusterTestFabricScoped>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterGeneratedCommandListAttributeCallback
      implements ChipClusters.UnitTestingCluster.GeneratedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterAcceptedCommandListAttributeCallback
      implements ChipClusters.UnitTestingCluster.AcceptedCommandListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public static class DelegatedUnitTestingClusterAttributeListAttributeCallback
      implements ChipClusters.UnitTestingCluster.AttributeListAttributeCallback,
          DelegatedClusterCallback {
    private ClusterCommandCallback callback;

    @Override
    public void setCallbackDelegate(ClusterCommandCallback callback) {
      this.callback = callback;
    }

    @Override
    public void onSuccess(List<Long> valueList) {
      Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
      CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List<Long>");
      responseValues.put(commandResponseInfo, valueList);
      callback.onSuccess(responseValues);
    }

    @Override
    public void onError(Exception ex) {
      callback.onFailure(ex);
    }
  }

  public Map<String, ClusterInfo> getClusterMap() {
    Map<String, ClusterInfo> clusterMap = initializeClusterMap();
    Map<String, Map<String, InteractionInfo>> commandMap = getCommandMap();
    combineCommand(clusterMap, commandMap);
    Map<String, Map<String, InteractionInfo>> readAttributeMap =
        new ClusterReadMapping().getReadAttributeMap();
    combineCommand(clusterMap, readAttributeMap);
    Map<String, Map<String, InteractionInfo>> writeAttributeMap =
        new ClusterWriteMapping().getWriteAttributeMap();
    combineCommand(clusterMap, writeAttributeMap);
    return clusterMap;
  }

  public Map<String, ClusterInfo> initializeClusterMap() {
    Map<String, ClusterInfo> clusterMap = new HashMap<>();
    ClusterInfo identifyClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.IdentifyCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("identify", identifyClusterInfo);
    ClusterInfo groupsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.GroupsCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("groups", groupsClusterInfo);
    ClusterInfo scenesClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ScenesCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("scenes", scenesClusterInfo);
    ClusterInfo onOffClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.OnOffCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("onOff", onOffClusterInfo);
    ClusterInfo onOffSwitchConfigurationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.OnOffSwitchConfigurationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("onOffSwitchConfiguration", onOffSwitchConfigurationClusterInfo);
    ClusterInfo levelControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.LevelControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("levelControl", levelControlClusterInfo);
    ClusterInfo binaryInputBasicClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BinaryInputBasicCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("binaryInputBasic", binaryInputBasicClusterInfo);
    ClusterInfo descriptorClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.DescriptorCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("descriptor", descriptorClusterInfo);
    ClusterInfo bindingClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BindingCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("binding", bindingClusterInfo);
    ClusterInfo accessControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.AccessControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("accessControl", accessControlClusterInfo);
    ClusterInfo actionsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ActionsCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("actions", actionsClusterInfo);
    ClusterInfo basicInformationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BasicInformationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("basicInformation", basicInformationClusterInfo);
    ClusterInfo otaSoftwareUpdateProviderClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.OtaSoftwareUpdateProviderCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("otaSoftwareUpdateProvider", otaSoftwareUpdateProviderClusterInfo);
    ClusterInfo otaSoftwareUpdateRequestorClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.OtaSoftwareUpdateRequestorCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("otaSoftwareUpdateRequestor", otaSoftwareUpdateRequestorClusterInfo);
    ClusterInfo localizationConfigurationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.LocalizationConfigurationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("localizationConfiguration", localizationConfigurationClusterInfo);
    ClusterInfo timeFormatLocalizationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.TimeFormatLocalizationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("timeFormatLocalization", timeFormatLocalizationClusterInfo);
    ClusterInfo unitLocalizationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.UnitLocalizationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("unitLocalization", unitLocalizationClusterInfo);
    ClusterInfo powerSourceConfigurationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.PowerSourceConfigurationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("powerSourceConfiguration", powerSourceConfigurationClusterInfo);
    ClusterInfo powerSourceClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.PowerSourceCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("powerSource", powerSourceClusterInfo);
    ClusterInfo generalCommissioningClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.GeneralCommissioningCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("generalCommissioning", generalCommissioningClusterInfo);
    ClusterInfo networkCommissioningClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.NetworkCommissioningCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("networkCommissioning", networkCommissioningClusterInfo);
    ClusterInfo diagnosticLogsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.DiagnosticLogsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("diagnosticLogs", diagnosticLogsClusterInfo);
    ClusterInfo generalDiagnosticsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.GeneralDiagnosticsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("generalDiagnostics", generalDiagnosticsClusterInfo);
    ClusterInfo softwareDiagnosticsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.SoftwareDiagnosticsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("softwareDiagnostics", softwareDiagnosticsClusterInfo);
    ClusterInfo threadNetworkDiagnosticsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ThreadNetworkDiagnosticsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("threadNetworkDiagnostics", threadNetworkDiagnosticsClusterInfo);
    ClusterInfo wiFiNetworkDiagnosticsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.WiFiNetworkDiagnosticsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("wiFiNetworkDiagnostics", wiFiNetworkDiagnosticsClusterInfo);
    ClusterInfo ethernetNetworkDiagnosticsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.EthernetNetworkDiagnosticsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("ethernetNetworkDiagnostics", ethernetNetworkDiagnosticsClusterInfo);
    ClusterInfo bridgedDeviceBasicClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BridgedDeviceBasicCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("bridgedDeviceBasic", bridgedDeviceBasicClusterInfo);
    ClusterInfo switchClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.SwitchCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("switch", switchClusterInfo);
    ClusterInfo administratorCommissioningClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.AdministratorCommissioningCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("administratorCommissioning", administratorCommissioningClusterInfo);
    ClusterInfo operationalCredentialsClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.OperationalCredentialsCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("operationalCredentials", operationalCredentialsClusterInfo);
    ClusterInfo groupKeyManagementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.GroupKeyManagementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("groupKeyManagement", groupKeyManagementClusterInfo);
    ClusterInfo fixedLabelClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.FixedLabelCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("fixedLabel", fixedLabelClusterInfo);
    ClusterInfo userLabelClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.UserLabelCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("userLabel", userLabelClusterInfo);
    ClusterInfo booleanStateClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BooleanStateCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("booleanState", booleanStateClusterInfo);
    ClusterInfo modeSelectClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ModeSelectCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("modeSelect", modeSelectClusterInfo);
    ClusterInfo doorLockClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.DoorLockCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("doorLock", doorLockClusterInfo);
    ClusterInfo windowCoveringClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.WindowCoveringCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("windowCovering", windowCoveringClusterInfo);
    ClusterInfo barrierControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BarrierControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("barrierControl", barrierControlClusterInfo);
    ClusterInfo pumpConfigurationAndControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.PumpConfigurationAndControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("pumpConfigurationAndControl", pumpConfigurationAndControlClusterInfo);
    ClusterInfo thermostatClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ThermostatCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("thermostat", thermostatClusterInfo);
    ClusterInfo fanControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.FanControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("fanControl", fanControlClusterInfo);
    ClusterInfo thermostatUserInterfaceConfigurationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.ThermostatUserInterfaceConfigurationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put(
        "thermostatUserInterfaceConfiguration", thermostatUserInterfaceConfigurationClusterInfo);
    ClusterInfo colorControlClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ColorControlCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("colorControl", colorControlClusterInfo);
    ClusterInfo ballastConfigurationClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.BallastConfigurationCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("ballastConfiguration", ballastConfigurationClusterInfo);
    ClusterInfo illuminanceMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.IlluminanceMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("illuminanceMeasurement", illuminanceMeasurementClusterInfo);
    ClusterInfo temperatureMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.TemperatureMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("temperatureMeasurement", temperatureMeasurementClusterInfo);
    ClusterInfo pressureMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.PressureMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("pressureMeasurement", pressureMeasurementClusterInfo);
    ClusterInfo flowMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.FlowMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("flowMeasurement", flowMeasurementClusterInfo);
    ClusterInfo relativeHumidityMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) ->
                new ChipClusters.RelativeHumidityMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("relativeHumidityMeasurement", relativeHumidityMeasurementClusterInfo);
    ClusterInfo occupancySensingClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.OccupancySensingCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("occupancySensing", occupancySensingClusterInfo);
    ClusterInfo wakeOnLanClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.WakeOnLanCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("wakeOnLan", wakeOnLanClusterInfo);
    ClusterInfo channelClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ChannelCluster(ptr, endpointId), new HashMap<>());
    clusterMap.put("channel", channelClusterInfo);
    ClusterInfo targetNavigatorClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.TargetNavigatorCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("targetNavigator", targetNavigatorClusterInfo);
    ClusterInfo mediaPlaybackClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.MediaPlaybackCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("mediaPlayback", mediaPlaybackClusterInfo);
    ClusterInfo mediaInputClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.MediaInputCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("mediaInput", mediaInputClusterInfo);
    ClusterInfo lowPowerClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.LowPowerCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("lowPower", lowPowerClusterInfo);
    ClusterInfo keypadInputClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.KeypadInputCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("keypadInput", keypadInputClusterInfo);
    ClusterInfo contentLauncherClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ContentLauncherCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("contentLauncher", contentLauncherClusterInfo);
    ClusterInfo audioOutputClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.AudioOutputCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("audioOutput", audioOutputClusterInfo);
    ClusterInfo applicationLauncherClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ApplicationLauncherCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("applicationLauncher", applicationLauncherClusterInfo);
    ClusterInfo applicationBasicClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ApplicationBasicCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("applicationBasic", applicationBasicClusterInfo);
    ClusterInfo accountLoginClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.AccountLoginCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("accountLogin", accountLoginClusterInfo);
    ClusterInfo electricalMeasurementClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.ElectricalMeasurementCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("electricalMeasurement", electricalMeasurementClusterInfo);
    ClusterInfo unitTestingClusterInfo =
        new ClusterInfo(
            (ptr, endpointId) -> new ChipClusters.UnitTestingCluster(ptr, endpointId),
            new HashMap<>());
    clusterMap.put("unitTesting", unitTestingClusterInfo);
    return clusterMap;
  }

  public void combineCommand(
      Map<String, ClusterInfo> destination, Map<String, Map<String, InteractionInfo>> source) {
    destination.get("identify").combineCommands(source.get("identify"));
    destination.get("groups").combineCommands(source.get("groups"));
    destination.get("scenes").combineCommands(source.get("scenes"));
    destination.get("onOff").combineCommands(source.get("onOff"));
    destination
        .get("onOffSwitchConfiguration")
        .combineCommands(source.get("onOffSwitchConfiguration"));
    destination.get("levelControl").combineCommands(source.get("levelControl"));
    destination.get("binaryInputBasic").combineCommands(source.get("binaryInputBasic"));
    destination.get("descriptor").combineCommands(source.get("descriptor"));
    destination.get("binding").combineCommands(source.get("binding"));
    destination.get("accessControl").combineCommands(source.get("accessControl"));
    destination.get("actions").combineCommands(source.get("actions"));
    destination.get("basicInformation").combineCommands(source.get("basicInformation"));
    destination
        .get("otaSoftwareUpdateProvider")
        .combineCommands(source.get("otaSoftwareUpdateProvider"));
    destination
        .get("otaSoftwareUpdateRequestor")
        .combineCommands(source.get("otaSoftwareUpdateRequestor"));
    destination
        .get("localizationConfiguration")
        .combineCommands(source.get("localizationConfiguration"));
    destination.get("timeFormatLocalization").combineCommands(source.get("timeFormatLocalization"));
    destination.get("unitLocalization").combineCommands(source.get("unitLocalization"));
    destination
        .get("powerSourceConfiguration")
        .combineCommands(source.get("powerSourceConfiguration"));
    destination.get("powerSource").combineCommands(source.get("powerSource"));
    destination.get("generalCommissioning").combineCommands(source.get("generalCommissioning"));
    destination.get("networkCommissioning").combineCommands(source.get("networkCommissioning"));
    destination.get("diagnosticLogs").combineCommands(source.get("diagnosticLogs"));
    destination.get("generalDiagnostics").combineCommands(source.get("generalDiagnostics"));
    destination.get("softwareDiagnostics").combineCommands(source.get("softwareDiagnostics"));
    destination
        .get("threadNetworkDiagnostics")
        .combineCommands(source.get("threadNetworkDiagnostics"));
    destination.get("wiFiNetworkDiagnostics").combineCommands(source.get("wiFiNetworkDiagnostics"));
    destination
        .get("ethernetNetworkDiagnostics")
        .combineCommands(source.get("ethernetNetworkDiagnostics"));
    destination.get("bridgedDeviceBasic").combineCommands(source.get("bridgedDeviceBasic"));
    destination.get("switch").combineCommands(source.get("switch"));
    destination
        .get("administratorCommissioning")
        .combineCommands(source.get("administratorCommissioning"));
    destination.get("operationalCredentials").combineCommands(source.get("operationalCredentials"));
    destination.get("groupKeyManagement").combineCommands(source.get("groupKeyManagement"));
    destination.get("fixedLabel").combineCommands(source.get("fixedLabel"));
    destination.get("userLabel").combineCommands(source.get("userLabel"));
    destination.get("booleanState").combineCommands(source.get("booleanState"));
    destination.get("modeSelect").combineCommands(source.get("modeSelect"));
    destination.get("doorLock").combineCommands(source.get("doorLock"));
    destination.get("windowCovering").combineCommands(source.get("windowCovering"));
    destination.get("barrierControl").combineCommands(source.get("barrierControl"));
    destination
        .get("pumpConfigurationAndControl")
        .combineCommands(source.get("pumpConfigurationAndControl"));
    destination.get("thermostat").combineCommands(source.get("thermostat"));
    destination.get("fanControl").combineCommands(source.get("fanControl"));
    destination
        .get("thermostatUserInterfaceConfiguration")
        .combineCommands(source.get("thermostatUserInterfaceConfiguration"));
    destination.get("colorControl").combineCommands(source.get("colorControl"));
    destination.get("ballastConfiguration").combineCommands(source.get("ballastConfiguration"));
    destination.get("illuminanceMeasurement").combineCommands(source.get("illuminanceMeasurement"));
    destination.get("temperatureMeasurement").combineCommands(source.get("temperatureMeasurement"));
    destination.get("pressureMeasurement").combineCommands(source.get("pressureMeasurement"));
    destination.get("flowMeasurement").combineCommands(source.get("flowMeasurement"));
    destination
        .get("relativeHumidityMeasurement")
        .combineCommands(source.get("relativeHumidityMeasurement"));
    destination.get("occupancySensing").combineCommands(source.get("occupancySensing"));
    destination.get("wakeOnLan").combineCommands(source.get("wakeOnLan"));
    destination.get("channel").combineCommands(source.get("channel"));
    destination.get("targetNavigator").combineCommands(source.get("targetNavigator"));
    destination.get("mediaPlayback").combineCommands(source.get("mediaPlayback"));
    destination.get("mediaInput").combineCommands(source.get("mediaInput"));
    destination.get("lowPower").combineCommands(source.get("lowPower"));
    destination.get("keypadInput").combineCommands(source.get("keypadInput"));
    destination.get("contentLauncher").combineCommands(source.get("contentLauncher"));
    destination.get("audioOutput").combineCommands(source.get("audioOutput"));
    destination.get("applicationLauncher").combineCommands(source.get("applicationLauncher"));
    destination.get("applicationBasic").combineCommands(source.get("applicationBasic"));
    destination.get("accountLogin").combineCommands(source.get("accountLogin"));
    destination.get("electricalMeasurement").combineCommands(source.get("electricalMeasurement"));
    destination.get("unitTesting").combineCommands(source.get("unitTesting"));
  }

  @SuppressWarnings("unchecked")
  public Map<String, Map<String, InteractionInfo>> getCommandMap() {
    Map<String, Map<String, InteractionInfo>> commandMap = new HashMap<>();
    Map<String, InteractionInfo> identifyClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> identifyidentifyCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo identifyidentifyidentifyTimeCommandParameterInfo =
        new CommandParameterInfo("identifyTime", Integer.class, Integer.class);
    identifyidentifyCommandParams.put(
        "identifyTime", identifyidentifyidentifyTimeCommandParameterInfo);

    InteractionInfo identifyidentifyInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.IdentifyCluster) cluster)
                  .identify(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("identifyTime"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            identifyidentifyCommandParams);
    identifyClusterInteractionInfoMap.put("identify", identifyidentifyInteractionInfo);
    Map<String, CommandParameterInfo> identifytriggerEffectCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo identifytriggerEffecteffectIdentifierCommandParameterInfo =
        new CommandParameterInfo("effectIdentifier", Integer.class, Integer.class);
    identifytriggerEffectCommandParams.put(
        "effectIdentifier", identifytriggerEffecteffectIdentifierCommandParameterInfo);

    CommandParameterInfo identifytriggerEffecteffectVariantCommandParameterInfo =
        new CommandParameterInfo("effectVariant", Integer.class, Integer.class);
    identifytriggerEffectCommandParams.put(
        "effectVariant", identifytriggerEffecteffectVariantCommandParameterInfo);

    InteractionInfo identifytriggerEffectInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.IdentifyCluster) cluster)
                  .triggerEffect(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("effectIdentifier"),
                      (Integer) commandArguments.get("effectVariant"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            identifytriggerEffectCommandParams);
    identifyClusterInteractionInfoMap.put("triggerEffect", identifytriggerEffectInteractionInfo);
    commandMap.put("identify", identifyClusterInteractionInfoMap);
    Map<String, InteractionInfo> groupsClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> groupsaddGroupCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupsaddGroupgroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    groupsaddGroupCommandParams.put("groupID", groupsaddGroupgroupIDCommandParameterInfo);

    CommandParameterInfo groupsaddGroupgroupNameCommandParameterInfo =
        new CommandParameterInfo("groupName", String.class, String.class);
    groupsaddGroupCommandParams.put("groupName", groupsaddGroupgroupNameCommandParameterInfo);

    InteractionInfo groupsaddGroupInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .addGroup(
                      (ChipClusters.GroupsCluster.AddGroupResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"),
                      (String) commandArguments.get("groupName"));
            },
            () -> new DelegatedAddGroupResponseCallback(),
            groupsaddGroupCommandParams);
    groupsClusterInteractionInfoMap.put("addGroup", groupsaddGroupInteractionInfo);
    Map<String, CommandParameterInfo> groupsviewGroupCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupsviewGroupgroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    groupsviewGroupCommandParams.put("groupID", groupsviewGroupgroupIDCommandParameterInfo);

    InteractionInfo groupsviewGroupInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .viewGroup(
                      (ChipClusters.GroupsCluster.ViewGroupResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"));
            },
            () -> new DelegatedViewGroupResponseCallback(),
            groupsviewGroupCommandParams);
    groupsClusterInteractionInfoMap.put("viewGroup", groupsviewGroupInteractionInfo);
    Map<String, CommandParameterInfo> groupsgetGroupMembershipCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupsgetGroupMembershipgroupListCommandParameterInfo =
        new CommandParameterInfo("groupList", ArrayList.class, Object.class);
    groupsgetGroupMembershipCommandParams.put(
        "groupList", groupsgetGroupMembershipgroupListCommandParameterInfo);

    InteractionInfo groupsgetGroupMembershipInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .getGroupMembership(
                      (ChipClusters.GroupsCluster.GetGroupMembershipResponseCallback) callback,
                      (ArrayList<Integer>) commandArguments.get("groupList"));
            },
            () -> new DelegatedGetGroupMembershipResponseCallback(),
            groupsgetGroupMembershipCommandParams);
    groupsClusterInteractionInfoMap.put(
        "getGroupMembership", groupsgetGroupMembershipInteractionInfo);
    Map<String, CommandParameterInfo> groupsremoveGroupCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupsremoveGroupgroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    groupsremoveGroupCommandParams.put("groupID", groupsremoveGroupgroupIDCommandParameterInfo);

    InteractionInfo groupsremoveGroupInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .removeGroup(
                      (ChipClusters.GroupsCluster.RemoveGroupResponseCallback) callback,
                      (Integer) commandArguments.get("groupID"));
            },
            () -> new DelegatedRemoveGroupResponseCallback(),
            groupsremoveGroupCommandParams);
    groupsClusterInteractionInfoMap.put("removeGroup", groupsremoveGroupInteractionInfo);
    Map<String, CommandParameterInfo> groupsremoveAllGroupsCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo groupsremoveAllGroupsInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .removeAllGroups((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            groupsremoveAllGroupsCommandParams);
    groupsClusterInteractionInfoMap.put("removeAllGroups", groupsremoveAllGroupsInteractionInfo);
    Map<String, CommandParameterInfo> groupsaddGroupIfIdentifyingCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupsaddGroupIfIdentifyinggroupIDCommandParameterInfo =
        new CommandParameterInfo("groupID", Integer.class, Integer.class);
    groupsaddGroupIfIdentifyingCommandParams.put(
        "groupID", groupsaddGroupIfIdentifyinggroupIDCommandParameterInfo);

    CommandParameterInfo groupsaddGroupIfIdentifyinggroupNameCommandParameterInfo =
        new CommandParameterInfo("groupName", String.class, String.class);
    groupsaddGroupIfIdentifyingCommandParams.put(
        "groupName", groupsaddGroupIfIdentifyinggroupNameCommandParameterInfo);

    InteractionInfo groupsaddGroupIfIdentifyingInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupsCluster) cluster)
                  .addGroupIfIdentifying(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("groupID"),
                      (String) commandArguments.get("groupName"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            groupsaddGroupIfIdentifyingCommandParams);
    groupsClusterInteractionInfoMap.put(
        "addGroupIfIdentifying", groupsaddGroupIfIdentifyingInteractionInfo);
    commandMap.put("groups", groupsClusterInteractionInfoMap);
    Map<String, InteractionInfo> scenesClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> scenesaddSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesaddScenegroupIdCommandParameterInfo =
        new CommandParameterInfo("groupId", Integer.class, Integer.class);
    scenesaddSceneCommandParams.put("groupId", scenesaddScenegroupIdCommandParameterInfo);

    CommandParameterInfo scenesaddScenesceneIdCommandParameterInfo =
        new CommandParameterInfo("sceneId", Integer.class, Integer.class);
    scenesaddSceneCommandParams.put("sceneId", scenesaddScenesceneIdCommandParameterInfo);

    CommandParameterInfo scenesaddScenetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    scenesaddSceneCommandParams.put(
        "transitionTime", scenesaddScenetransitionTimeCommandParameterInfo);

    CommandParameterInfo scenesaddScenesceneNameCommandParameterInfo =
        new CommandParameterInfo("sceneName", String.class, String.class);
    scenesaddSceneCommandParams.put("sceneName", scenesaddScenesceneNameCommandParameterInfo);

    InteractionInfo scenesaddSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .addScene(
                      (ChipClusters.ScenesCluster.AddSceneResponseCallback) callback,
                      (Integer) commandArguments.get("groupId"),
                      (Integer) commandArguments.get("sceneId"),
                      (Integer) commandArguments.get("transitionTime"),
                      (String) commandArguments.get("sceneName"),
                      (ArrayList<ChipStructs.ScenesClusterExtensionFieldSet>)
                          commandArguments.get("extensionFieldSets"));
            },
            () -> new DelegatedAddSceneResponseCallback(),
            scenesaddSceneCommandParams);
    scenesClusterInteractionInfoMap.put("addScene", scenesaddSceneInteractionInfo);
    Map<String, CommandParameterInfo> scenesviewSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesviewScenegroupIdCommandParameterInfo =
        new CommandParameterInfo("groupId", Integer.class, Integer.class);
    scenesviewSceneCommandParams.put("groupId", scenesviewScenegroupIdCommandParameterInfo);

    CommandParameterInfo scenesviewScenesceneIdCommandParameterInfo =
        new CommandParameterInfo("sceneId", Integer.class, Integer.class);
    scenesviewSceneCommandParams.put("sceneId", scenesviewScenesceneIdCommandParameterInfo);

    InteractionInfo scenesviewSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .viewScene(
                      (ChipClusters.ScenesCluster.ViewSceneResponseCallback) callback,
                      (Integer) commandArguments.get("groupId"),
                      (Integer) commandArguments.get("sceneId"));
            },
            () -> new DelegatedViewSceneResponseCallback(),
            scenesviewSceneCommandParams);
    scenesClusterInteractionInfoMap.put("viewScene", scenesviewSceneInteractionInfo);
    Map<String, CommandParameterInfo> scenesremoveSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesremoveScenegroupIdCommandParameterInfo =
        new CommandParameterInfo("groupId", Integer.class, Integer.class);
    scenesremoveSceneCommandParams.put("groupId", scenesremoveScenegroupIdCommandParameterInfo);

    CommandParameterInfo scenesremoveScenesceneIdCommandParameterInfo =
        new CommandParameterInfo("sceneId", Integer.class, Integer.class);
    scenesremoveSceneCommandParams.put("sceneId", scenesremoveScenesceneIdCommandParameterInfo);

    InteractionInfo scenesremoveSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .removeScene(
                      (ChipClusters.ScenesCluster.RemoveSceneResponseCallback) callback,
                      (Integer) commandArguments.get("groupId"),
                      (Integer) commandArguments.get("sceneId"));
            },
            () -> new DelegatedRemoveSceneResponseCallback(),
            scenesremoveSceneCommandParams);
    scenesClusterInteractionInfoMap.put("removeScene", scenesremoveSceneInteractionInfo);
    Map<String, CommandParameterInfo> scenesremoveAllScenesCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesremoveAllScenesgroupIdCommandParameterInfo =
        new CommandParameterInfo("groupId", Integer.class, Integer.class);
    scenesremoveAllScenesCommandParams.put(
        "groupId", scenesremoveAllScenesgroupIdCommandParameterInfo);

    InteractionInfo scenesremoveAllScenesInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .removeAllScenes(
                      (ChipClusters.ScenesCluster.RemoveAllScenesResponseCallback) callback,
                      (Integer) commandArguments.get("groupId"));
            },
            () -> new DelegatedRemoveAllScenesResponseCallback(),
            scenesremoveAllScenesCommandParams);
    scenesClusterInteractionInfoMap.put("removeAllScenes", scenesremoveAllScenesInteractionInfo);
    Map<String, CommandParameterInfo> scenesstoreSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesstoreScenegroupIdCommandParameterInfo =
        new CommandParameterInfo("groupId", Integer.class, Integer.class);
    scenesstoreSceneCommandParams.put("groupId", scenesstoreScenegroupIdCommandParameterInfo);

    CommandParameterInfo scenesstoreScenesceneIdCommandParameterInfo =
        new CommandParameterInfo("sceneId", Integer.class, Integer.class);
    scenesstoreSceneCommandParams.put("sceneId", scenesstoreScenesceneIdCommandParameterInfo);

    InteractionInfo scenesstoreSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .storeScene(
                      (ChipClusters.ScenesCluster.StoreSceneResponseCallback) callback,
                      (Integer) commandArguments.get("groupId"),
                      (Integer) commandArguments.get("sceneId"));
            },
            () -> new DelegatedStoreSceneResponseCallback(),
            scenesstoreSceneCommandParams);
    scenesClusterInteractionInfoMap.put("storeScene", scenesstoreSceneInteractionInfo);
    Map<String, CommandParameterInfo> scenesrecallSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesrecallScenegroupIdCommandParameterInfo =
        new CommandParameterInfo("groupId", Integer.class, Integer.class);
    scenesrecallSceneCommandParams.put("groupId", scenesrecallScenegroupIdCommandParameterInfo);

    CommandParameterInfo scenesrecallScenesceneIdCommandParameterInfo =
        new CommandParameterInfo("sceneId", Integer.class, Integer.class);
    scenesrecallSceneCommandParams.put("sceneId", scenesrecallScenesceneIdCommandParameterInfo);

    CommandParameterInfo scenesrecallScenetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Optional.class, Integer.class);
    scenesrecallSceneCommandParams.put(
        "transitionTime", scenesrecallScenetransitionTimeCommandParameterInfo);

    InteractionInfo scenesrecallSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .recallScene(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("groupId"),
                      (Integer) commandArguments.get("sceneId"),
                      (Optional<Integer>) commandArguments.get("transitionTime"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            scenesrecallSceneCommandParams);
    scenesClusterInteractionInfoMap.put("recallScene", scenesrecallSceneInteractionInfo);
    Map<String, CommandParameterInfo> scenesgetSceneMembershipCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo scenesgetSceneMembershipgroupIdCommandParameterInfo =
        new CommandParameterInfo("groupId", Integer.class, Integer.class);
    scenesgetSceneMembershipCommandParams.put(
        "groupId", scenesgetSceneMembershipgroupIdCommandParameterInfo);

    InteractionInfo scenesgetSceneMembershipInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ScenesCluster) cluster)
                  .getSceneMembership(
                      (ChipClusters.ScenesCluster.GetSceneMembershipResponseCallback) callback,
                      (Integer) commandArguments.get("groupId"));
            },
            () -> new DelegatedGetSceneMembershipResponseCallback(),
            scenesgetSceneMembershipCommandParams);
    scenesClusterInteractionInfoMap.put(
        "getSceneMembership", scenesgetSceneMembershipInteractionInfo);
    commandMap.put("scenes", scenesClusterInteractionInfoMap);
    Map<String, InteractionInfo> onOffClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> onOffoffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo onOffoffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster).off((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOffoffCommandParams);
    onOffClusterInteractionInfoMap.put("off", onOffoffInteractionInfo);
    Map<String, CommandParameterInfo> onOffonCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo onOffonInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster).on((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOffonCommandParams);
    onOffClusterInteractionInfoMap.put("on", onOffonInteractionInfo);
    Map<String, CommandParameterInfo> onOfftoggleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo onOfftoggleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster).toggle((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOfftoggleCommandParams);
    onOffClusterInteractionInfoMap.put("toggle", onOfftoggleInteractionInfo);
    Map<String, CommandParameterInfo> onOffoffWithEffectCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo onOffoffWithEffecteffectIdentifierCommandParameterInfo =
        new CommandParameterInfo("effectIdentifier", Integer.class, Integer.class);
    onOffoffWithEffectCommandParams.put(
        "effectIdentifier", onOffoffWithEffecteffectIdentifierCommandParameterInfo);

    CommandParameterInfo onOffoffWithEffecteffectVariantCommandParameterInfo =
        new CommandParameterInfo("effectVariant", Integer.class, Integer.class);
    onOffoffWithEffectCommandParams.put(
        "effectVariant", onOffoffWithEffecteffectVariantCommandParameterInfo);

    InteractionInfo onOffoffWithEffectInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster)
                  .offWithEffect(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("effectIdentifier"),
                      (Integer) commandArguments.get("effectVariant"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOffoffWithEffectCommandParams);
    onOffClusterInteractionInfoMap.put("offWithEffect", onOffoffWithEffectInteractionInfo);
    Map<String, CommandParameterInfo> onOffonWithRecallGlobalSceneCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo onOffonWithRecallGlobalSceneInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster)
                  .onWithRecallGlobalScene((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOffonWithRecallGlobalSceneCommandParams);
    onOffClusterInteractionInfoMap.put(
        "onWithRecallGlobalScene", onOffonWithRecallGlobalSceneInteractionInfo);
    Map<String, CommandParameterInfo> onOffonWithTimedOffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo onOffonWithTimedOffonOffControlCommandParameterInfo =
        new CommandParameterInfo("onOffControl", Integer.class, Integer.class);
    onOffonWithTimedOffCommandParams.put(
        "onOffControl", onOffonWithTimedOffonOffControlCommandParameterInfo);

    CommandParameterInfo onOffonWithTimedOffonTimeCommandParameterInfo =
        new CommandParameterInfo("onTime", Integer.class, Integer.class);
    onOffonWithTimedOffCommandParams.put("onTime", onOffonWithTimedOffonTimeCommandParameterInfo);

    CommandParameterInfo onOffonWithTimedOffoffWaitTimeCommandParameterInfo =
        new CommandParameterInfo("offWaitTime", Integer.class, Integer.class);
    onOffonWithTimedOffCommandParams.put(
        "offWaitTime", onOffonWithTimedOffoffWaitTimeCommandParameterInfo);

    InteractionInfo onOffonWithTimedOffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OnOffCluster) cluster)
                  .onWithTimedOff(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("onOffControl"),
                      (Integer) commandArguments.get("onTime"),
                      (Integer) commandArguments.get("offWaitTime"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            onOffonWithTimedOffCommandParams);
    onOffClusterInteractionInfoMap.put("onWithTimedOff", onOffonWithTimedOffInteractionInfo);
    commandMap.put("onOff", onOffClusterInteractionInfoMap);
    Map<String, InteractionInfo> onOffSwitchConfigurationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("onOffSwitchConfiguration", onOffSwitchConfigurationClusterInteractionInfoMap);
    Map<String, InteractionInfo> levelControlClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> levelControlmoveToLevelCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlmoveToLevellevelCommandParameterInfo =
        new CommandParameterInfo("level", Integer.class, Integer.class);
    levelControlmoveToLevelCommandParams.put(
        "level", levelControlmoveToLevellevelCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLeveltransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    levelControlmoveToLevelCommandParams.put(
        "transitionTime", levelControlmoveToLeveltransitionTimeCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLeveloptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlmoveToLevelCommandParams.put(
        "optionsMask", levelControlmoveToLeveloptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLeveloptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlmoveToLevelCommandParams.put(
        "optionsOverride", levelControlmoveToLeveloptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlmoveToLevelInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .moveToLevel(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("level"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlmoveToLevelCommandParams);
    levelControlClusterInteractionInfoMap.put(
        "moveToLevel", levelControlmoveToLevelInteractionInfo);
    Map<String, CommandParameterInfo> levelControlmoveCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlmovemoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    levelControlmoveCommandParams.put("moveMode", levelControlmovemoveModeCommandParameterInfo);

    CommandParameterInfo levelControlmoverateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    levelControlmoveCommandParams.put("rate", levelControlmoverateCommandParameterInfo);

    CommandParameterInfo levelControlmoveoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlmoveCommandParams.put(
        "optionsMask", levelControlmoveoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlmoveoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlmoveCommandParams.put(
        "optionsOverride", levelControlmoveoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlmoveInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .move(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlmoveCommandParams);
    levelControlClusterInteractionInfoMap.put("move", levelControlmoveInteractionInfo);
    Map<String, CommandParameterInfo> levelControlstepCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlstepstepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    levelControlstepCommandParams.put("stepMode", levelControlstepstepModeCommandParameterInfo);

    CommandParameterInfo levelControlstepstepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    levelControlstepCommandParams.put("stepSize", levelControlstepstepSizeCommandParameterInfo);

    CommandParameterInfo levelControlsteptransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    levelControlstepCommandParams.put(
        "transitionTime", levelControlsteptransitionTimeCommandParameterInfo);

    CommandParameterInfo levelControlstepoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlstepCommandParams.put(
        "optionsMask", levelControlstepoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlstepoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlstepCommandParams.put(
        "optionsOverride", levelControlstepoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlstepInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .step(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlstepCommandParams);
    levelControlClusterInteractionInfoMap.put("step", levelControlstepInteractionInfo);
    Map<String, CommandParameterInfo> levelControlstopCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlstopoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlstopCommandParams.put(
        "optionsMask", levelControlstopoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlstopoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlstopCommandParams.put(
        "optionsOverride", levelControlstopoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlstopInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .stop(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlstopCommandParams);
    levelControlClusterInteractionInfoMap.put("stop", levelControlstopInteractionInfo);
    Map<String, CommandParameterInfo> levelControlmoveToLevelWithOnOffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlmoveToLevelWithOnOfflevelCommandParameterInfo =
        new CommandParameterInfo("level", Integer.class, Integer.class);
    levelControlmoveToLevelWithOnOffCommandParams.put(
        "level", levelControlmoveToLevelWithOnOfflevelCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLevelWithOnOfftransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    levelControlmoveToLevelWithOnOffCommandParams.put(
        "transitionTime", levelControlmoveToLevelWithOnOfftransitionTimeCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLevelWithOnOffoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlmoveToLevelWithOnOffCommandParams.put(
        "optionsMask", levelControlmoveToLevelWithOnOffoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlmoveToLevelWithOnOffoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlmoveToLevelWithOnOffCommandParams.put(
        "optionsOverride", levelControlmoveToLevelWithOnOffoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlmoveToLevelWithOnOffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .moveToLevelWithOnOff(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("level"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlmoveToLevelWithOnOffCommandParams);
    levelControlClusterInteractionInfoMap.put(
        "moveToLevelWithOnOff", levelControlmoveToLevelWithOnOffInteractionInfo);
    Map<String, CommandParameterInfo> levelControlmoveWithOnOffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlmoveWithOnOffmoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    levelControlmoveWithOnOffCommandParams.put(
        "moveMode", levelControlmoveWithOnOffmoveModeCommandParameterInfo);

    CommandParameterInfo levelControlmoveWithOnOffrateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    levelControlmoveWithOnOffCommandParams.put(
        "rate", levelControlmoveWithOnOffrateCommandParameterInfo);

    CommandParameterInfo levelControlmoveWithOnOffoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlmoveWithOnOffCommandParams.put(
        "optionsMask", levelControlmoveWithOnOffoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlmoveWithOnOffoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlmoveWithOnOffCommandParams.put(
        "optionsOverride", levelControlmoveWithOnOffoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlmoveWithOnOffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .moveWithOnOff(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlmoveWithOnOffCommandParams);
    levelControlClusterInteractionInfoMap.put(
        "moveWithOnOff", levelControlmoveWithOnOffInteractionInfo);
    Map<String, CommandParameterInfo> levelControlstepWithOnOffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlstepWithOnOffstepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    levelControlstepWithOnOffCommandParams.put(
        "stepMode", levelControlstepWithOnOffstepModeCommandParameterInfo);

    CommandParameterInfo levelControlstepWithOnOffstepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    levelControlstepWithOnOffCommandParams.put(
        "stepSize", levelControlstepWithOnOffstepSizeCommandParameterInfo);

    CommandParameterInfo levelControlstepWithOnOfftransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    levelControlstepWithOnOffCommandParams.put(
        "transitionTime", levelControlstepWithOnOfftransitionTimeCommandParameterInfo);

    CommandParameterInfo levelControlstepWithOnOffoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlstepWithOnOffCommandParams.put(
        "optionsMask", levelControlstepWithOnOffoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlstepWithOnOffoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlstepWithOnOffCommandParams.put(
        "optionsOverride", levelControlstepWithOnOffoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlstepWithOnOffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .stepWithOnOff(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlstepWithOnOffCommandParams);
    levelControlClusterInteractionInfoMap.put(
        "stepWithOnOff", levelControlstepWithOnOffInteractionInfo);
    Map<String, CommandParameterInfo> levelControlstopWithOnOffCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo levelControlstopWithOnOffoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    levelControlstopWithOnOffCommandParams.put(
        "optionsMask", levelControlstopWithOnOffoptionsMaskCommandParameterInfo);

    CommandParameterInfo levelControlstopWithOnOffoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    levelControlstopWithOnOffCommandParams.put(
        "optionsOverride", levelControlstopWithOnOffoptionsOverrideCommandParameterInfo);

    InteractionInfo levelControlstopWithOnOffInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LevelControlCluster) cluster)
                  .stopWithOnOff(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            levelControlstopWithOnOffCommandParams);
    levelControlClusterInteractionInfoMap.put(
        "stopWithOnOff", levelControlstopWithOnOffInteractionInfo);
    commandMap.put("levelControl", levelControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> binaryInputBasicClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("binaryInputBasic", binaryInputBasicClusterInteractionInfoMap);
    Map<String, InteractionInfo> descriptorClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("descriptor", descriptorClusterInteractionInfoMap);
    Map<String, InteractionInfo> bindingClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("binding", bindingClusterInteractionInfoMap);
    Map<String, InteractionInfo> accessControlClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("accessControl", accessControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> actionsClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> actionsinstantActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsinstantActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsinstantActionCommandParams.put(
        "actionID", actionsinstantActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsinstantActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsinstantActionCommandParams.put(
        "invokeID", actionsinstantActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsinstantActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .instantAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsinstantActionCommandParams);
    actionsClusterInteractionInfoMap.put("instantAction", actionsinstantActionInteractionInfo);
    Map<String, CommandParameterInfo> actionsinstantActionWithTransitionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsinstantActionWithTransitionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsinstantActionWithTransitionCommandParams.put(
        "actionID", actionsinstantActionWithTransitionactionIDCommandParameterInfo);

    CommandParameterInfo actionsinstantActionWithTransitioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsinstantActionWithTransitionCommandParams.put(
        "invokeID", actionsinstantActionWithTransitioninvokeIDCommandParameterInfo);

    CommandParameterInfo actionsinstantActionWithTransitiontransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    actionsinstantActionWithTransitionCommandParams.put(
        "transitionTime", actionsinstantActionWithTransitiontransitionTimeCommandParameterInfo);

    InteractionInfo actionsinstantActionWithTransitionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .instantActionWithTransition(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Integer) commandArguments.get("transitionTime"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsinstantActionWithTransitionCommandParams);
    actionsClusterInteractionInfoMap.put(
        "instantActionWithTransition", actionsinstantActionWithTransitionInteractionInfo);
    Map<String, CommandParameterInfo> actionsstartActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsstartActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsstartActionCommandParams.put("actionID", actionsstartActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsstartActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsstartActionCommandParams.put("invokeID", actionsstartActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsstartActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .startAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsstartActionCommandParams);
    actionsClusterInteractionInfoMap.put("startAction", actionsstartActionInteractionInfo);
    Map<String, CommandParameterInfo> actionsstartActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsstartActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsstartActionWithDurationCommandParams.put(
        "actionID", actionsstartActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo actionsstartActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsstartActionWithDurationCommandParams.put(
        "invokeID", actionsstartActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo actionsstartActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    actionsstartActionWithDurationCommandParams.put(
        "duration", actionsstartActionWithDurationdurationCommandParameterInfo);

    InteractionInfo actionsstartActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .startActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsstartActionWithDurationCommandParams);
    actionsClusterInteractionInfoMap.put(
        "startActionWithDuration", actionsstartActionWithDurationInteractionInfo);
    Map<String, CommandParameterInfo> actionsstopActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsstopActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsstopActionCommandParams.put("actionID", actionsstopActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsstopActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsstopActionCommandParams.put("invokeID", actionsstopActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsstopActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .stopAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsstopActionCommandParams);
    actionsClusterInteractionInfoMap.put("stopAction", actionsstopActionInteractionInfo);
    Map<String, CommandParameterInfo> actionspauseActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionspauseActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionspauseActionCommandParams.put("actionID", actionspauseActionactionIDCommandParameterInfo);

    CommandParameterInfo actionspauseActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionspauseActionCommandParams.put("invokeID", actionspauseActioninvokeIDCommandParameterInfo);

    InteractionInfo actionspauseActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .pauseAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionspauseActionCommandParams);
    actionsClusterInteractionInfoMap.put("pauseAction", actionspauseActionInteractionInfo);
    Map<String, CommandParameterInfo> actionspauseActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionspauseActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionspauseActionWithDurationCommandParams.put(
        "actionID", actionspauseActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo actionspauseActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionspauseActionWithDurationCommandParams.put(
        "invokeID", actionspauseActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo actionspauseActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    actionspauseActionWithDurationCommandParams.put(
        "duration", actionspauseActionWithDurationdurationCommandParameterInfo);

    InteractionInfo actionspauseActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .pauseActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionspauseActionWithDurationCommandParams);
    actionsClusterInteractionInfoMap.put(
        "pauseActionWithDuration", actionspauseActionWithDurationInteractionInfo);
    Map<String, CommandParameterInfo> actionsresumeActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsresumeActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsresumeActionCommandParams.put(
        "actionID", actionsresumeActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsresumeActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsresumeActionCommandParams.put(
        "invokeID", actionsresumeActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsresumeActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .resumeAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsresumeActionCommandParams);
    actionsClusterInteractionInfoMap.put("resumeAction", actionsresumeActionInteractionInfo);
    Map<String, CommandParameterInfo> actionsenableActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsenableActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsenableActionCommandParams.put(
        "actionID", actionsenableActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsenableActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsenableActionCommandParams.put(
        "invokeID", actionsenableActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsenableActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .enableAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsenableActionCommandParams);
    actionsClusterInteractionInfoMap.put("enableAction", actionsenableActionInteractionInfo);
    Map<String, CommandParameterInfo> actionsenableActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsenableActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsenableActionWithDurationCommandParams.put(
        "actionID", actionsenableActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo actionsenableActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsenableActionWithDurationCommandParams.put(
        "invokeID", actionsenableActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo actionsenableActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    actionsenableActionWithDurationCommandParams.put(
        "duration", actionsenableActionWithDurationdurationCommandParameterInfo);

    InteractionInfo actionsenableActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .enableActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsenableActionWithDurationCommandParams);
    actionsClusterInteractionInfoMap.put(
        "enableActionWithDuration", actionsenableActionWithDurationInteractionInfo);
    Map<String, CommandParameterInfo> actionsdisableActionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsdisableActionactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsdisableActionCommandParams.put(
        "actionID", actionsdisableActionactionIDCommandParameterInfo);

    CommandParameterInfo actionsdisableActioninvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsdisableActionCommandParams.put(
        "invokeID", actionsdisableActioninvokeIDCommandParameterInfo);

    InteractionInfo actionsdisableActionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .disableAction(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsdisableActionCommandParams);
    actionsClusterInteractionInfoMap.put("disableAction", actionsdisableActionInteractionInfo);
    Map<String, CommandParameterInfo> actionsdisableActionWithDurationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo actionsdisableActionWithDurationactionIDCommandParameterInfo =
        new CommandParameterInfo("actionID", Integer.class, Integer.class);
    actionsdisableActionWithDurationCommandParams.put(
        "actionID", actionsdisableActionWithDurationactionIDCommandParameterInfo);

    CommandParameterInfo actionsdisableActionWithDurationinvokeIDCommandParameterInfo =
        new CommandParameterInfo("invokeID", Optional.class, Long.class);
    actionsdisableActionWithDurationCommandParams.put(
        "invokeID", actionsdisableActionWithDurationinvokeIDCommandParameterInfo);

    CommandParameterInfo actionsdisableActionWithDurationdurationCommandParameterInfo =
        new CommandParameterInfo("duration", Long.class, Long.class);
    actionsdisableActionWithDurationCommandParams.put(
        "duration", actionsdisableActionWithDurationdurationCommandParameterInfo);

    InteractionInfo actionsdisableActionWithDurationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ActionsCluster) cluster)
                  .disableActionWithDuration(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("actionID"),
                      (Optional<Long>) commandArguments.get("invokeID"),
                      (Long) commandArguments.get("duration"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            actionsdisableActionWithDurationCommandParams);
    actionsClusterInteractionInfoMap.put(
        "disableActionWithDuration", actionsdisableActionWithDurationInteractionInfo);
    commandMap.put("actions", actionsClusterInteractionInfoMap);
    Map<String, InteractionInfo> basicInformationClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("basicInformation", basicInformationClusterInteractionInfoMap);
    Map<String, InteractionInfo> otaSoftwareUpdateProviderClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> otaSoftwareUpdateProviderqueryImageCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo otaSoftwareUpdateProviderqueryImagevendorIDCommandParameterInfo =
        new CommandParameterInfo("vendorID", Integer.class, Integer.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "vendorID", otaSoftwareUpdateProviderqueryImagevendorIDCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderqueryImageproductIDCommandParameterInfo =
        new CommandParameterInfo("productID", Integer.class, Integer.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "productID", otaSoftwareUpdateProviderqueryImageproductIDCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderqueryImagesoftwareVersionCommandParameterInfo =
        new CommandParameterInfo("softwareVersion", Long.class, Long.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "softwareVersion", otaSoftwareUpdateProviderqueryImagesoftwareVersionCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderqueryImageprotocolsSupportedCommandParameterInfo =
        new CommandParameterInfo("protocolsSupported", ArrayList.class, Object.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "protocolsSupported",
        otaSoftwareUpdateProviderqueryImageprotocolsSupportedCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderqueryImagehardwareVersionCommandParameterInfo =
        new CommandParameterInfo("hardwareVersion", Optional.class, Integer.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "hardwareVersion", otaSoftwareUpdateProviderqueryImagehardwareVersionCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderqueryImagelocationCommandParameterInfo =
        new CommandParameterInfo("location", Optional.class, String.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "location", otaSoftwareUpdateProviderqueryImagelocationCommandParameterInfo);

    CommandParameterInfo
        otaSoftwareUpdateProviderqueryImagerequestorCanConsentCommandParameterInfo =
            new CommandParameterInfo("requestorCanConsent", Optional.class, Boolean.class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "requestorCanConsent",
        otaSoftwareUpdateProviderqueryImagerequestorCanConsentCommandParameterInfo);

    CommandParameterInfo
        otaSoftwareUpdateProviderqueryImagemetadataForProviderCommandParameterInfo =
            new CommandParameterInfo("metadataForProvider", Optional.class, byte[].class);
    otaSoftwareUpdateProviderqueryImageCommandParams.put(
        "metadataForProvider",
        otaSoftwareUpdateProviderqueryImagemetadataForProviderCommandParameterInfo);

    InteractionInfo otaSoftwareUpdateProviderqueryImageInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OtaSoftwareUpdateProviderCluster) cluster)
                  .queryImage(
                      (ChipClusters.OtaSoftwareUpdateProviderCluster.QueryImageResponseCallback)
                          callback,
                      (Integer) commandArguments.get("vendorID"),
                      (Integer) commandArguments.get("productID"),
                      (Long) commandArguments.get("softwareVersion"),
                      (ArrayList<Integer>) commandArguments.get("protocolsSupported"),
                      (Optional<Integer>) commandArguments.get("hardwareVersion"),
                      (Optional<String>) commandArguments.get("location"),
                      (Optional<Boolean>) commandArguments.get("requestorCanConsent"),
                      (Optional<byte[]>) commandArguments.get("metadataForProvider"));
            },
            () -> new DelegatedQueryImageResponseCallback(),
            otaSoftwareUpdateProviderqueryImageCommandParams);
    otaSoftwareUpdateProviderClusterInteractionInfoMap.put(
        "queryImage", otaSoftwareUpdateProviderqueryImageInteractionInfo);
    Map<String, CommandParameterInfo> otaSoftwareUpdateProviderapplyUpdateRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        otaSoftwareUpdateProviderapplyUpdateRequestupdateTokenCommandParameterInfo =
            new CommandParameterInfo("updateToken", byte[].class, byte[].class);
    otaSoftwareUpdateProviderapplyUpdateRequestCommandParams.put(
        "updateToken", otaSoftwareUpdateProviderapplyUpdateRequestupdateTokenCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateProviderapplyUpdateRequestnewVersionCommandParameterInfo =
        new CommandParameterInfo("newVersion", Long.class, Long.class);
    otaSoftwareUpdateProviderapplyUpdateRequestCommandParams.put(
        "newVersion", otaSoftwareUpdateProviderapplyUpdateRequestnewVersionCommandParameterInfo);

    InteractionInfo otaSoftwareUpdateProviderapplyUpdateRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OtaSoftwareUpdateProviderCluster) cluster)
                  .applyUpdateRequest(
                      (ChipClusters.OtaSoftwareUpdateProviderCluster.ApplyUpdateResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("updateToken"),
                      (Long) commandArguments.get("newVersion"));
            },
            () -> new DelegatedApplyUpdateResponseCallback(),
            otaSoftwareUpdateProviderapplyUpdateRequestCommandParams);
    otaSoftwareUpdateProviderClusterInteractionInfoMap.put(
        "applyUpdateRequest", otaSoftwareUpdateProviderapplyUpdateRequestInteractionInfo);
    Map<String, CommandParameterInfo> otaSoftwareUpdateProvidernotifyUpdateAppliedCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        otaSoftwareUpdateProvidernotifyUpdateAppliedupdateTokenCommandParameterInfo =
            new CommandParameterInfo("updateToken", byte[].class, byte[].class);
    otaSoftwareUpdateProvidernotifyUpdateAppliedCommandParams.put(
        "updateToken", otaSoftwareUpdateProvidernotifyUpdateAppliedupdateTokenCommandParameterInfo);

    CommandParameterInfo
        otaSoftwareUpdateProvidernotifyUpdateAppliedsoftwareVersionCommandParameterInfo =
            new CommandParameterInfo("softwareVersion", Long.class, Long.class);
    otaSoftwareUpdateProvidernotifyUpdateAppliedCommandParams.put(
        "softwareVersion",
        otaSoftwareUpdateProvidernotifyUpdateAppliedsoftwareVersionCommandParameterInfo);

    InteractionInfo otaSoftwareUpdateProvidernotifyUpdateAppliedInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OtaSoftwareUpdateProviderCluster) cluster)
                  .notifyUpdateApplied(
                      (DefaultClusterCallback) callback,
                      (byte[]) commandArguments.get("updateToken"),
                      (Long) commandArguments.get("softwareVersion"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            otaSoftwareUpdateProvidernotifyUpdateAppliedCommandParams);
    otaSoftwareUpdateProviderClusterInteractionInfoMap.put(
        "notifyUpdateApplied", otaSoftwareUpdateProvidernotifyUpdateAppliedInteractionInfo);
    commandMap.put("otaSoftwareUpdateProvider", otaSoftwareUpdateProviderClusterInteractionInfoMap);
    Map<String, InteractionInfo> otaSoftwareUpdateRequestorClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> otaSoftwareUpdateRequestorannounceOTAProviderCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        otaSoftwareUpdateRequestorannounceOTAProviderproviderNodeIDCommandParameterInfo =
            new CommandParameterInfo("providerNodeID", Long.class, Long.class);
    otaSoftwareUpdateRequestorannounceOTAProviderCommandParams.put(
        "providerNodeID",
        otaSoftwareUpdateRequestorannounceOTAProviderproviderNodeIDCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateRequestorannounceOTAProvidervendorIDCommandParameterInfo =
        new CommandParameterInfo("vendorID", Integer.class, Integer.class);
    otaSoftwareUpdateRequestorannounceOTAProviderCommandParams.put(
        "vendorID", otaSoftwareUpdateRequestorannounceOTAProvidervendorIDCommandParameterInfo);

    CommandParameterInfo
        otaSoftwareUpdateRequestorannounceOTAProviderannouncementReasonCommandParameterInfo =
            new CommandParameterInfo("announcementReason", Integer.class, Integer.class);
    otaSoftwareUpdateRequestorannounceOTAProviderCommandParams.put(
        "announcementReason",
        otaSoftwareUpdateRequestorannounceOTAProviderannouncementReasonCommandParameterInfo);

    CommandParameterInfo
        otaSoftwareUpdateRequestorannounceOTAProvidermetadataForNodeCommandParameterInfo =
            new CommandParameterInfo("metadataForNode", Optional.class, byte[].class);
    otaSoftwareUpdateRequestorannounceOTAProviderCommandParams.put(
        "metadataForNode",
        otaSoftwareUpdateRequestorannounceOTAProvidermetadataForNodeCommandParameterInfo);

    CommandParameterInfo otaSoftwareUpdateRequestorannounceOTAProviderendpointCommandParameterInfo =
        new CommandParameterInfo("endpoint", Integer.class, Integer.class);
    otaSoftwareUpdateRequestorannounceOTAProviderCommandParams.put(
        "endpoint", otaSoftwareUpdateRequestorannounceOTAProviderendpointCommandParameterInfo);

    InteractionInfo otaSoftwareUpdateRequestorannounceOTAProviderInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OtaSoftwareUpdateRequestorCluster) cluster)
                  .announceOTAProvider(
                      (DefaultClusterCallback) callback,
                      (Long) commandArguments.get("providerNodeID"),
                      (Integer) commandArguments.get("vendorID"),
                      (Integer) commandArguments.get("announcementReason"),
                      (Optional<byte[]>) commandArguments.get("metadataForNode"),
                      (Integer) commandArguments.get("endpoint"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            otaSoftwareUpdateRequestorannounceOTAProviderCommandParams);
    otaSoftwareUpdateRequestorClusterInteractionInfoMap.put(
        "announceOTAProvider", otaSoftwareUpdateRequestorannounceOTAProviderInteractionInfo);
    commandMap.put(
        "otaSoftwareUpdateRequestor", otaSoftwareUpdateRequestorClusterInteractionInfoMap);
    Map<String, InteractionInfo> localizationConfigurationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("localizationConfiguration", localizationConfigurationClusterInteractionInfoMap);
    Map<String, InteractionInfo> timeFormatLocalizationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("timeFormatLocalization", timeFormatLocalizationClusterInteractionInfoMap);
    Map<String, InteractionInfo> unitLocalizationClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("unitLocalization", unitLocalizationClusterInteractionInfoMap);
    Map<String, InteractionInfo> powerSourceConfigurationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("powerSourceConfiguration", powerSourceConfigurationClusterInteractionInfoMap);
    Map<String, InteractionInfo> powerSourceClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("powerSource", powerSourceClusterInteractionInfoMap);
    Map<String, InteractionInfo> generalCommissioningClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> generalCommissioningarmFailSafeCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo generalCommissioningarmFailSafeexpiryLengthSecondsCommandParameterInfo =
        new CommandParameterInfo("expiryLengthSeconds", Integer.class, Integer.class);
    generalCommissioningarmFailSafeCommandParams.put(
        "expiryLengthSeconds",
        generalCommissioningarmFailSafeexpiryLengthSecondsCommandParameterInfo);

    CommandParameterInfo generalCommissioningarmFailSafebreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Long.class, Long.class);
    generalCommissioningarmFailSafeCommandParams.put(
        "breadcrumb", generalCommissioningarmFailSafebreadcrumbCommandParameterInfo);

    InteractionInfo generalCommissioningarmFailSafeInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GeneralCommissioningCluster) cluster)
                  .armFailSafe(
                      (ChipClusters.GeneralCommissioningCluster.ArmFailSafeResponseCallback)
                          callback,
                      (Integer) commandArguments.get("expiryLengthSeconds"),
                      (Long) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedArmFailSafeResponseCallback(),
            generalCommissioningarmFailSafeCommandParams);
    generalCommissioningClusterInteractionInfoMap.put(
        "armFailSafe", generalCommissioningarmFailSafeInteractionInfo);
    Map<String, CommandParameterInfo> generalCommissioningsetRegulatoryConfigCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        generalCommissioningsetRegulatoryConfignewRegulatoryConfigCommandParameterInfo =
            new CommandParameterInfo("newRegulatoryConfig", Integer.class, Integer.class);
    generalCommissioningsetRegulatoryConfigCommandParams.put(
        "newRegulatoryConfig",
        generalCommissioningsetRegulatoryConfignewRegulatoryConfigCommandParameterInfo);

    CommandParameterInfo generalCommissioningsetRegulatoryConfigcountryCodeCommandParameterInfo =
        new CommandParameterInfo("countryCode", String.class, String.class);
    generalCommissioningsetRegulatoryConfigCommandParams.put(
        "countryCode", generalCommissioningsetRegulatoryConfigcountryCodeCommandParameterInfo);

    CommandParameterInfo generalCommissioningsetRegulatoryConfigbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Long.class, Long.class);
    generalCommissioningsetRegulatoryConfigCommandParams.put(
        "breadcrumb", generalCommissioningsetRegulatoryConfigbreadcrumbCommandParameterInfo);

    InteractionInfo generalCommissioningsetRegulatoryConfigInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GeneralCommissioningCluster) cluster)
                  .setRegulatoryConfig(
                      (ChipClusters.GeneralCommissioningCluster.SetRegulatoryConfigResponseCallback)
                          callback,
                      (Integer) commandArguments.get("newRegulatoryConfig"),
                      (String) commandArguments.get("countryCode"),
                      (Long) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedSetRegulatoryConfigResponseCallback(),
            generalCommissioningsetRegulatoryConfigCommandParams);
    generalCommissioningClusterInteractionInfoMap.put(
        "setRegulatoryConfig", generalCommissioningsetRegulatoryConfigInteractionInfo);
    Map<String, CommandParameterInfo> generalCommissioningcommissioningCompleteCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo generalCommissioningcommissioningCompleteInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GeneralCommissioningCluster) cluster)
                  .commissioningComplete(
                      (ChipClusters.GeneralCommissioningCluster
                              .CommissioningCompleteResponseCallback)
                          callback);
            },
            () -> new DelegatedCommissioningCompleteResponseCallback(),
            generalCommissioningcommissioningCompleteCommandParams);
    generalCommissioningClusterInteractionInfoMap.put(
        "commissioningComplete", generalCommissioningcommissioningCompleteInteractionInfo);
    commandMap.put("generalCommissioning", generalCommissioningClusterInteractionInfoMap);
    Map<String, InteractionInfo> networkCommissioningClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> networkCommissioningscanNetworksCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo networkCommissioningscanNetworksssidCommandParameterInfo =
        new CommandParameterInfo("ssid", Optional.class, byte[].class);
    networkCommissioningscanNetworksCommandParams.put(
        "ssid", networkCommissioningscanNetworksssidCommandParameterInfo);

    CommandParameterInfo networkCommissioningscanNetworksbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningscanNetworksCommandParams.put(
        "breadcrumb", networkCommissioningscanNetworksbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningscanNetworksInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .scanNetworks(
                      (ChipClusters.NetworkCommissioningCluster.ScanNetworksResponseCallback)
                          callback,
                      (Optional<byte[]>) commandArguments.get("ssid"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedScanNetworksResponseCallback(),
            networkCommissioningscanNetworksCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "scanNetworks", networkCommissioningscanNetworksInteractionInfo);
    Map<String, CommandParameterInfo> networkCommissioningaddOrUpdateWiFiNetworkCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo networkCommissioningaddOrUpdateWiFiNetworkssidCommandParameterInfo =
        new CommandParameterInfo("ssid", byte[].class, byte[].class);
    networkCommissioningaddOrUpdateWiFiNetworkCommandParams.put(
        "ssid", networkCommissioningaddOrUpdateWiFiNetworkssidCommandParameterInfo);

    CommandParameterInfo networkCommissioningaddOrUpdateWiFiNetworkcredentialsCommandParameterInfo =
        new CommandParameterInfo("credentials", byte[].class, byte[].class);
    networkCommissioningaddOrUpdateWiFiNetworkCommandParams.put(
        "credentials", networkCommissioningaddOrUpdateWiFiNetworkcredentialsCommandParameterInfo);

    CommandParameterInfo networkCommissioningaddOrUpdateWiFiNetworkbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningaddOrUpdateWiFiNetworkCommandParams.put(
        "breadcrumb", networkCommissioningaddOrUpdateWiFiNetworkbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningaddOrUpdateWiFiNetworkInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .addOrUpdateWiFiNetwork(
                      (ChipClusters.NetworkCommissioningCluster.NetworkConfigResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("ssid"),
                      (byte[]) commandArguments.get("credentials"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedNetworkConfigResponseCallback(),
            networkCommissioningaddOrUpdateWiFiNetworkCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "addOrUpdateWiFiNetwork", networkCommissioningaddOrUpdateWiFiNetworkInteractionInfo);
    Map<String, CommandParameterInfo> networkCommissioningaddOrUpdateThreadNetworkCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        networkCommissioningaddOrUpdateThreadNetworkoperationalDatasetCommandParameterInfo =
            new CommandParameterInfo("operationalDataset", byte[].class, byte[].class);
    networkCommissioningaddOrUpdateThreadNetworkCommandParams.put(
        "operationalDataset",
        networkCommissioningaddOrUpdateThreadNetworkoperationalDatasetCommandParameterInfo);

    CommandParameterInfo
        networkCommissioningaddOrUpdateThreadNetworkbreadcrumbCommandParameterInfo =
            new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningaddOrUpdateThreadNetworkCommandParams.put(
        "breadcrumb", networkCommissioningaddOrUpdateThreadNetworkbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningaddOrUpdateThreadNetworkInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .addOrUpdateThreadNetwork(
                      (ChipClusters.NetworkCommissioningCluster.NetworkConfigResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("operationalDataset"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedNetworkConfigResponseCallback(),
            networkCommissioningaddOrUpdateThreadNetworkCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "addOrUpdateThreadNetwork", networkCommissioningaddOrUpdateThreadNetworkInteractionInfo);
    Map<String, CommandParameterInfo> networkCommissioningremoveNetworkCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo networkCommissioningremoveNetworknetworkIDCommandParameterInfo =
        new CommandParameterInfo("networkID", byte[].class, byte[].class);
    networkCommissioningremoveNetworkCommandParams.put(
        "networkID", networkCommissioningremoveNetworknetworkIDCommandParameterInfo);

    CommandParameterInfo networkCommissioningremoveNetworkbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningremoveNetworkCommandParams.put(
        "breadcrumb", networkCommissioningremoveNetworkbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningremoveNetworkInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .removeNetwork(
                      (ChipClusters.NetworkCommissioningCluster.NetworkConfigResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("networkID"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedNetworkConfigResponseCallback(),
            networkCommissioningremoveNetworkCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "removeNetwork", networkCommissioningremoveNetworkInteractionInfo);
    Map<String, CommandParameterInfo> networkCommissioningconnectNetworkCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo networkCommissioningconnectNetworknetworkIDCommandParameterInfo =
        new CommandParameterInfo("networkID", byte[].class, byte[].class);
    networkCommissioningconnectNetworkCommandParams.put(
        "networkID", networkCommissioningconnectNetworknetworkIDCommandParameterInfo);

    CommandParameterInfo networkCommissioningconnectNetworkbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningconnectNetworkCommandParams.put(
        "breadcrumb", networkCommissioningconnectNetworkbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningconnectNetworkInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .connectNetwork(
                      (ChipClusters.NetworkCommissioningCluster.ConnectNetworkResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("networkID"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedConnectNetworkResponseCallback(),
            networkCommissioningconnectNetworkCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "connectNetwork", networkCommissioningconnectNetworkInteractionInfo);
    Map<String, CommandParameterInfo> networkCommissioningreorderNetworkCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo networkCommissioningreorderNetworknetworkIDCommandParameterInfo =
        new CommandParameterInfo("networkID", byte[].class, byte[].class);
    networkCommissioningreorderNetworkCommandParams.put(
        "networkID", networkCommissioningreorderNetworknetworkIDCommandParameterInfo);

    CommandParameterInfo networkCommissioningreorderNetworknetworkIndexCommandParameterInfo =
        new CommandParameterInfo("networkIndex", Integer.class, Integer.class);
    networkCommissioningreorderNetworkCommandParams.put(
        "networkIndex", networkCommissioningreorderNetworknetworkIndexCommandParameterInfo);

    CommandParameterInfo networkCommissioningreorderNetworkbreadcrumbCommandParameterInfo =
        new CommandParameterInfo("breadcrumb", Optional.class, Long.class);
    networkCommissioningreorderNetworkCommandParams.put(
        "breadcrumb", networkCommissioningreorderNetworkbreadcrumbCommandParameterInfo);

    InteractionInfo networkCommissioningreorderNetworkInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.NetworkCommissioningCluster) cluster)
                  .reorderNetwork(
                      (ChipClusters.NetworkCommissioningCluster.NetworkConfigResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("networkID"),
                      (Integer) commandArguments.get("networkIndex"),
                      (Optional<Long>) commandArguments.get("breadcrumb"));
            },
            () -> new DelegatedNetworkConfigResponseCallback(),
            networkCommissioningreorderNetworkCommandParams);
    networkCommissioningClusterInteractionInfoMap.put(
        "reorderNetwork", networkCommissioningreorderNetworkInteractionInfo);
    commandMap.put("networkCommissioning", networkCommissioningClusterInteractionInfoMap);
    Map<String, InteractionInfo> diagnosticLogsClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> diagnosticLogsretrieveLogsRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo diagnosticLogsretrieveLogsRequestintentCommandParameterInfo =
        new CommandParameterInfo("intent", Integer.class, Integer.class);
    diagnosticLogsretrieveLogsRequestCommandParams.put(
        "intent", diagnosticLogsretrieveLogsRequestintentCommandParameterInfo);

    CommandParameterInfo diagnosticLogsretrieveLogsRequestrequestedProtocolCommandParameterInfo =
        new CommandParameterInfo("requestedProtocol", Integer.class, Integer.class);
    diagnosticLogsretrieveLogsRequestCommandParams.put(
        "requestedProtocol",
        diagnosticLogsretrieveLogsRequestrequestedProtocolCommandParameterInfo);

    CommandParameterInfo
        diagnosticLogsretrieveLogsRequesttransferFileDesignatorCommandParameterInfo =
            new CommandParameterInfo("transferFileDesignator", byte[].class, byte[].class);
    diagnosticLogsretrieveLogsRequestCommandParams.put(
        "transferFileDesignator",
        diagnosticLogsretrieveLogsRequesttransferFileDesignatorCommandParameterInfo);

    InteractionInfo diagnosticLogsretrieveLogsRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DiagnosticLogsCluster) cluster)
                  .retrieveLogsRequest(
                      (ChipClusters.DiagnosticLogsCluster.RetrieveLogsResponseCallback) callback,
                      (Integer) commandArguments.get("intent"),
                      (Integer) commandArguments.get("requestedProtocol"),
                      (byte[]) commandArguments.get("transferFileDesignator"));
            },
            () -> new DelegatedRetrieveLogsResponseCallback(),
            diagnosticLogsretrieveLogsRequestCommandParams);
    diagnosticLogsClusterInteractionInfoMap.put(
        "retrieveLogsRequest", diagnosticLogsretrieveLogsRequestInteractionInfo);
    commandMap.put("diagnosticLogs", diagnosticLogsClusterInteractionInfoMap);
    Map<String, InteractionInfo> generalDiagnosticsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> generalDiagnosticstestEventTriggerCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo generalDiagnosticstestEventTriggerenableKeyCommandParameterInfo =
        new CommandParameterInfo("enableKey", byte[].class, byte[].class);
    generalDiagnosticstestEventTriggerCommandParams.put(
        "enableKey", generalDiagnosticstestEventTriggerenableKeyCommandParameterInfo);

    CommandParameterInfo generalDiagnosticstestEventTriggereventTriggerCommandParameterInfo =
        new CommandParameterInfo("eventTrigger", Long.class, Long.class);
    generalDiagnosticstestEventTriggerCommandParams.put(
        "eventTrigger", generalDiagnosticstestEventTriggereventTriggerCommandParameterInfo);

    InteractionInfo generalDiagnosticstestEventTriggerInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GeneralDiagnosticsCluster) cluster)
                  .testEventTrigger(
                      (DefaultClusterCallback) callback,
                      (byte[]) commandArguments.get("enableKey"),
                      (Long) commandArguments.get("eventTrigger"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            generalDiagnosticstestEventTriggerCommandParams);
    generalDiagnosticsClusterInteractionInfoMap.put(
        "testEventTrigger", generalDiagnosticstestEventTriggerInteractionInfo);
    commandMap.put("generalDiagnostics", generalDiagnosticsClusterInteractionInfoMap);
    Map<String, InteractionInfo> softwareDiagnosticsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> softwareDiagnosticsresetWatermarksCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo softwareDiagnosticsresetWatermarksInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.SoftwareDiagnosticsCluster) cluster)
                  .resetWatermarks((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            softwareDiagnosticsresetWatermarksCommandParams);
    softwareDiagnosticsClusterInteractionInfoMap.put(
        "resetWatermarks", softwareDiagnosticsresetWatermarksInteractionInfo);
    commandMap.put("softwareDiagnostics", softwareDiagnosticsClusterInteractionInfoMap);
    Map<String, InteractionInfo> threadNetworkDiagnosticsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> threadNetworkDiagnosticsresetCountsCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo threadNetworkDiagnosticsresetCountsInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ThreadNetworkDiagnosticsCluster) cluster)
                  .resetCounts((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            threadNetworkDiagnosticsresetCountsCommandParams);
    threadNetworkDiagnosticsClusterInteractionInfoMap.put(
        "resetCounts", threadNetworkDiagnosticsresetCountsInteractionInfo);
    commandMap.put("threadNetworkDiagnostics", threadNetworkDiagnosticsClusterInteractionInfoMap);
    Map<String, InteractionInfo> wiFiNetworkDiagnosticsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> wiFiNetworkDiagnosticsresetCountsCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo wiFiNetworkDiagnosticsresetCountsInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WiFiNetworkDiagnosticsCluster) cluster)
                  .resetCounts((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            wiFiNetworkDiagnosticsresetCountsCommandParams);
    wiFiNetworkDiagnosticsClusterInteractionInfoMap.put(
        "resetCounts", wiFiNetworkDiagnosticsresetCountsInteractionInfo);
    commandMap.put("wiFiNetworkDiagnostics", wiFiNetworkDiagnosticsClusterInteractionInfoMap);
    Map<String, InteractionInfo> ethernetNetworkDiagnosticsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> ethernetNetworkDiagnosticsresetCountsCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo ethernetNetworkDiagnosticsresetCountsInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.EthernetNetworkDiagnosticsCluster) cluster)
                  .resetCounts((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            ethernetNetworkDiagnosticsresetCountsCommandParams);
    ethernetNetworkDiagnosticsClusterInteractionInfoMap.put(
        "resetCounts", ethernetNetworkDiagnosticsresetCountsInteractionInfo);
    commandMap.put(
        "ethernetNetworkDiagnostics", ethernetNetworkDiagnosticsClusterInteractionInfoMap);
    Map<String, InteractionInfo> bridgedDeviceBasicClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("bridgedDeviceBasic", bridgedDeviceBasicClusterInteractionInfoMap);
    Map<String, InteractionInfo> switchClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("switch", switchClusterInteractionInfoMap);
    Map<String, InteractionInfo> administratorCommissioningClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo>
        administratorCommissioningopenCommissioningWindowCommandParams =
            new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        administratorCommissioningopenCommissioningWindowcommissioningTimeoutCommandParameterInfo =
            new CommandParameterInfo("commissioningTimeout", Integer.class, Integer.class);
    administratorCommissioningopenCommissioningWindowCommandParams.put(
        "commissioningTimeout",
        administratorCommissioningopenCommissioningWindowcommissioningTimeoutCommandParameterInfo);

    CommandParameterInfo
        administratorCommissioningopenCommissioningWindowPAKEVerifierCommandParameterInfo =
            new CommandParameterInfo("PAKEVerifier", byte[].class, byte[].class);
    administratorCommissioningopenCommissioningWindowCommandParams.put(
        "PAKEVerifier",
        administratorCommissioningopenCommissioningWindowPAKEVerifierCommandParameterInfo);

    CommandParameterInfo
        administratorCommissioningopenCommissioningWindowdiscriminatorCommandParameterInfo =
            new CommandParameterInfo("discriminator", Integer.class, Integer.class);
    administratorCommissioningopenCommissioningWindowCommandParams.put(
        "discriminator",
        administratorCommissioningopenCommissioningWindowdiscriminatorCommandParameterInfo);

    CommandParameterInfo
        administratorCommissioningopenCommissioningWindowiterationsCommandParameterInfo =
            new CommandParameterInfo("iterations", Long.class, Long.class);
    administratorCommissioningopenCommissioningWindowCommandParams.put(
        "iterations",
        administratorCommissioningopenCommissioningWindowiterationsCommandParameterInfo);

    CommandParameterInfo administratorCommissioningopenCommissioningWindowsaltCommandParameterInfo =
        new CommandParameterInfo("salt", byte[].class, byte[].class);
    administratorCommissioningopenCommissioningWindowCommandParams.put(
        "salt", administratorCommissioningopenCommissioningWindowsaltCommandParameterInfo);

    InteractionInfo administratorCommissioningopenCommissioningWindowInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AdministratorCommissioningCluster) cluster)
                  .openCommissioningWindow(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("commissioningTimeout"),
                      (byte[]) commandArguments.get("PAKEVerifier"),
                      (Integer) commandArguments.get("discriminator"),
                      (Long) commandArguments.get("iterations"),
                      (byte[]) commandArguments.get("salt"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            administratorCommissioningopenCommissioningWindowCommandParams);
    administratorCommissioningClusterInteractionInfoMap.put(
        "openCommissioningWindow",
        administratorCommissioningopenCommissioningWindowInteractionInfo);
    Map<String, CommandParameterInfo>
        administratorCommissioningopenBasicCommissioningWindowCommandParams =
            new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        administratorCommissioningopenBasicCommissioningWindowcommissioningTimeoutCommandParameterInfo =
            new CommandParameterInfo("commissioningTimeout", Integer.class, Integer.class);
    administratorCommissioningopenBasicCommissioningWindowCommandParams.put(
        "commissioningTimeout",
        administratorCommissioningopenBasicCommissioningWindowcommissioningTimeoutCommandParameterInfo);

    InteractionInfo administratorCommissioningopenBasicCommissioningWindowInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AdministratorCommissioningCluster) cluster)
                  .openBasicCommissioningWindow(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("commissioningTimeout"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            administratorCommissioningopenBasicCommissioningWindowCommandParams);
    administratorCommissioningClusterInteractionInfoMap.put(
        "openBasicCommissioningWindow",
        administratorCommissioningopenBasicCommissioningWindowInteractionInfo);
    Map<String, CommandParameterInfo> administratorCommissioningrevokeCommissioningCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo administratorCommissioningrevokeCommissioningInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AdministratorCommissioningCluster) cluster)
                  .revokeCommissioning((DefaultClusterCallback) callback, 10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            administratorCommissioningrevokeCommissioningCommandParams);
    administratorCommissioningClusterInteractionInfoMap.put(
        "revokeCommissioning", administratorCommissioningrevokeCommissioningInteractionInfo);
    commandMap.put(
        "administratorCommissioning", administratorCommissioningClusterInteractionInfoMap);
    Map<String, InteractionInfo> operationalCredentialsClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> operationalCredentialsattestationRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        operationalCredentialsattestationRequestattestationNonceCommandParameterInfo =
            new CommandParameterInfo("attestationNonce", byte[].class, byte[].class);
    operationalCredentialsattestationRequestCommandParams.put(
        "attestationNonce",
        operationalCredentialsattestationRequestattestationNonceCommandParameterInfo);

    InteractionInfo operationalCredentialsattestationRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .attestationRequest(
                      (ChipClusters.OperationalCredentialsCluster.AttestationResponseCallback)
                          callback,
                      (byte[]) commandArguments.get("attestationNonce"));
            },
            () -> new DelegatedAttestationResponseCallback(),
            operationalCredentialsattestationRequestCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "attestationRequest", operationalCredentialsattestationRequestInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialscertificateChainRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        operationalCredentialscertificateChainRequestcertificateTypeCommandParameterInfo =
            new CommandParameterInfo("certificateType", Integer.class, Integer.class);
    operationalCredentialscertificateChainRequestCommandParams.put(
        "certificateType",
        operationalCredentialscertificateChainRequestcertificateTypeCommandParameterInfo);

    InteractionInfo operationalCredentialscertificateChainRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .certificateChainRequest(
                      (ChipClusters.OperationalCredentialsCluster.CertificateChainResponseCallback)
                          callback,
                      (Integer) commandArguments.get("certificateType"));
            },
            () -> new DelegatedCertificateChainResponseCallback(),
            operationalCredentialscertificateChainRequestCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "certificateChainRequest", operationalCredentialscertificateChainRequestInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsCSRRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo operationalCredentialsCSRRequestCSRNonceCommandParameterInfo =
        new CommandParameterInfo("CSRNonce", byte[].class, byte[].class);
    operationalCredentialsCSRRequestCommandParams.put(
        "CSRNonce", operationalCredentialsCSRRequestCSRNonceCommandParameterInfo);

    CommandParameterInfo operationalCredentialsCSRRequestisForUpdateNOCCommandParameterInfo =
        new CommandParameterInfo("isForUpdateNOC", Optional.class, Boolean.class);
    operationalCredentialsCSRRequestCommandParams.put(
        "isForUpdateNOC", operationalCredentialsCSRRequestisForUpdateNOCCommandParameterInfo);

    InteractionInfo operationalCredentialsCSRRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .CSRRequest(
                      (ChipClusters.OperationalCredentialsCluster.CSRResponseCallback) callback,
                      (byte[]) commandArguments.get("CSRNonce"),
                      (Optional<Boolean>) commandArguments.get("isForUpdateNOC"));
            },
            () -> new DelegatedCSRResponseCallback(),
            operationalCredentialsCSRRequestCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "CSRRequest", operationalCredentialsCSRRequestInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsaddNOCCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo operationalCredentialsaddNOCNOCValueCommandParameterInfo =
        new CommandParameterInfo("NOCValue", byte[].class, byte[].class);
    operationalCredentialsaddNOCCommandParams.put(
        "NOCValue", operationalCredentialsaddNOCNOCValueCommandParameterInfo);

    CommandParameterInfo operationalCredentialsaddNOCICACValueCommandParameterInfo =
        new CommandParameterInfo("ICACValue", Optional.class, byte[].class);
    operationalCredentialsaddNOCCommandParams.put(
        "ICACValue", operationalCredentialsaddNOCICACValueCommandParameterInfo);

    CommandParameterInfo operationalCredentialsaddNOCIPKValueCommandParameterInfo =
        new CommandParameterInfo("IPKValue", byte[].class, byte[].class);
    operationalCredentialsaddNOCCommandParams.put(
        "IPKValue", operationalCredentialsaddNOCIPKValueCommandParameterInfo);

    CommandParameterInfo operationalCredentialsaddNOCcaseAdminSubjectCommandParameterInfo =
        new CommandParameterInfo("caseAdminSubject", Long.class, Long.class);
    operationalCredentialsaddNOCCommandParams.put(
        "caseAdminSubject", operationalCredentialsaddNOCcaseAdminSubjectCommandParameterInfo);

    CommandParameterInfo operationalCredentialsaddNOCadminVendorIdCommandParameterInfo =
        new CommandParameterInfo("adminVendorId", Integer.class, Integer.class);
    operationalCredentialsaddNOCCommandParams.put(
        "adminVendorId", operationalCredentialsaddNOCadminVendorIdCommandParameterInfo);

    InteractionInfo operationalCredentialsaddNOCInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .addNOC(
                      (ChipClusters.OperationalCredentialsCluster.NOCResponseCallback) callback,
                      (byte[]) commandArguments.get("NOCValue"),
                      (Optional<byte[]>) commandArguments.get("ICACValue"),
                      (byte[]) commandArguments.get("IPKValue"),
                      (Long) commandArguments.get("caseAdminSubject"),
                      (Integer) commandArguments.get("adminVendorId"));
            },
            () -> new DelegatedNOCResponseCallback(),
            operationalCredentialsaddNOCCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "addNOC", operationalCredentialsaddNOCInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsupdateNOCCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo operationalCredentialsupdateNOCNOCValueCommandParameterInfo =
        new CommandParameterInfo("NOCValue", byte[].class, byte[].class);
    operationalCredentialsupdateNOCCommandParams.put(
        "NOCValue", operationalCredentialsupdateNOCNOCValueCommandParameterInfo);

    CommandParameterInfo operationalCredentialsupdateNOCICACValueCommandParameterInfo =
        new CommandParameterInfo("ICACValue", Optional.class, byte[].class);
    operationalCredentialsupdateNOCCommandParams.put(
        "ICACValue", operationalCredentialsupdateNOCICACValueCommandParameterInfo);

    InteractionInfo operationalCredentialsupdateNOCInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .updateNOC(
                      (ChipClusters.OperationalCredentialsCluster.NOCResponseCallback) callback,
                      (byte[]) commandArguments.get("NOCValue"),
                      (Optional<byte[]>) commandArguments.get("ICACValue"));
            },
            () -> new DelegatedNOCResponseCallback(),
            operationalCredentialsupdateNOCCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "updateNOC", operationalCredentialsupdateNOCInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsupdateFabricLabelCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo operationalCredentialsupdateFabricLabellabelCommandParameterInfo =
        new CommandParameterInfo("label", String.class, String.class);
    operationalCredentialsupdateFabricLabelCommandParams.put(
        "label", operationalCredentialsupdateFabricLabellabelCommandParameterInfo);

    InteractionInfo operationalCredentialsupdateFabricLabelInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .updateFabricLabel(
                      (ChipClusters.OperationalCredentialsCluster.NOCResponseCallback) callback,
                      (String) commandArguments.get("label"));
            },
            () -> new DelegatedNOCResponseCallback(),
            operationalCredentialsupdateFabricLabelCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "updateFabricLabel", operationalCredentialsupdateFabricLabelInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsremoveFabricCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo operationalCredentialsremoveFabricfabricIndexCommandParameterInfo =
        new CommandParameterInfo("fabricIndex", Integer.class, Integer.class);
    operationalCredentialsremoveFabricCommandParams.put(
        "fabricIndex", operationalCredentialsremoveFabricfabricIndexCommandParameterInfo);

    InteractionInfo operationalCredentialsremoveFabricInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .removeFabric(
                      (ChipClusters.OperationalCredentialsCluster.NOCResponseCallback) callback,
                      (Integer) commandArguments.get("fabricIndex"));
            },
            () -> new DelegatedNOCResponseCallback(),
            operationalCredentialsremoveFabricCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "removeFabric", operationalCredentialsremoveFabricInteractionInfo);
    Map<String, CommandParameterInfo> operationalCredentialsaddTrustedRootCertificateCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        operationalCredentialsaddTrustedRootCertificaterootCertificateCommandParameterInfo =
            new CommandParameterInfo("rootCertificate", byte[].class, byte[].class);
    operationalCredentialsaddTrustedRootCertificateCommandParams.put(
        "rootCertificate",
        operationalCredentialsaddTrustedRootCertificaterootCertificateCommandParameterInfo);

    InteractionInfo operationalCredentialsaddTrustedRootCertificateInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.OperationalCredentialsCluster) cluster)
                  .addTrustedRootCertificate(
                      (DefaultClusterCallback) callback,
                      (byte[]) commandArguments.get("rootCertificate"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            operationalCredentialsaddTrustedRootCertificateCommandParams);
    operationalCredentialsClusterInteractionInfoMap.put(
        "addTrustedRootCertificate",
        operationalCredentialsaddTrustedRootCertificateInteractionInfo);
    commandMap.put("operationalCredentials", operationalCredentialsClusterInteractionInfoMap);
    Map<String, InteractionInfo> groupKeyManagementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> groupKeyManagementkeySetWriteCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo groupKeyManagementkeySetWriteInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupKeyManagementCluster) cluster)
                  .keySetWrite(
                      (DefaultClusterCallback) callback,
                      (ChipStructs.GroupKeyManagementClusterGroupKeySetStruct)
                          commandArguments.get("groupKeySet"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            groupKeyManagementkeySetWriteCommandParams);
    groupKeyManagementClusterInteractionInfoMap.put(
        "keySetWrite", groupKeyManagementkeySetWriteInteractionInfo);
    Map<String, CommandParameterInfo> groupKeyManagementkeySetReadCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupKeyManagementkeySetReadgroupKeySetIDCommandParameterInfo =
        new CommandParameterInfo("groupKeySetID", Integer.class, Integer.class);
    groupKeyManagementkeySetReadCommandParams.put(
        "groupKeySetID", groupKeyManagementkeySetReadgroupKeySetIDCommandParameterInfo);

    InteractionInfo groupKeyManagementkeySetReadInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupKeyManagementCluster) cluster)
                  .keySetRead(
                      (ChipClusters.GroupKeyManagementCluster.KeySetReadResponseCallback) callback,
                      (Integer) commandArguments.get("groupKeySetID"));
            },
            () -> new DelegatedKeySetReadResponseCallback(),
            groupKeyManagementkeySetReadCommandParams);
    groupKeyManagementClusterInteractionInfoMap.put(
        "keySetRead", groupKeyManagementkeySetReadInteractionInfo);
    Map<String, CommandParameterInfo> groupKeyManagementkeySetRemoveCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupKeyManagementkeySetRemovegroupKeySetIDCommandParameterInfo =
        new CommandParameterInfo("groupKeySetID", Integer.class, Integer.class);
    groupKeyManagementkeySetRemoveCommandParams.put(
        "groupKeySetID", groupKeyManagementkeySetRemovegroupKeySetIDCommandParameterInfo);

    InteractionInfo groupKeyManagementkeySetRemoveInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupKeyManagementCluster) cluster)
                  .keySetRemove(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("groupKeySetID"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            groupKeyManagementkeySetRemoveCommandParams);
    groupKeyManagementClusterInteractionInfoMap.put(
        "keySetRemove", groupKeyManagementkeySetRemoveInteractionInfo);
    Map<String, CommandParameterInfo> groupKeyManagementkeySetReadAllIndicesCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo groupKeyManagementkeySetReadAllIndicesgroupKeySetIDsCommandParameterInfo =
        new CommandParameterInfo("groupKeySetIDs", ArrayList.class, Object.class);
    groupKeyManagementkeySetReadAllIndicesCommandParams.put(
        "groupKeySetIDs", groupKeyManagementkeySetReadAllIndicesgroupKeySetIDsCommandParameterInfo);

    InteractionInfo groupKeyManagementkeySetReadAllIndicesInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.GroupKeyManagementCluster) cluster)
                  .keySetReadAllIndices(
                      (ChipClusters.GroupKeyManagementCluster.KeySetReadAllIndicesResponseCallback)
                          callback,
                      (ArrayList<Integer>) commandArguments.get("groupKeySetIDs"));
            },
            () -> new DelegatedKeySetReadAllIndicesResponseCallback(),
            groupKeyManagementkeySetReadAllIndicesCommandParams);
    groupKeyManagementClusterInteractionInfoMap.put(
        "keySetReadAllIndices", groupKeyManagementkeySetReadAllIndicesInteractionInfo);
    commandMap.put("groupKeyManagement", groupKeyManagementClusterInteractionInfoMap);
    Map<String, InteractionInfo> fixedLabelClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("fixedLabel", fixedLabelClusterInteractionInfoMap);
    Map<String, InteractionInfo> userLabelClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("userLabel", userLabelClusterInteractionInfoMap);
    Map<String, InteractionInfo> booleanStateClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("booleanState", booleanStateClusterInteractionInfoMap);
    Map<String, InteractionInfo> modeSelectClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> modeSelectchangeToModeCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo modeSelectchangeToModenewModeCommandParameterInfo =
        new CommandParameterInfo("newMode", Integer.class, Integer.class);
    modeSelectchangeToModeCommandParams.put(
        "newMode", modeSelectchangeToModenewModeCommandParameterInfo);

    InteractionInfo modeSelectchangeToModeInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ModeSelectCluster) cluster)
                  .changeToMode(
                      (DefaultClusterCallback) callback, (Integer) commandArguments.get("newMode"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            modeSelectchangeToModeCommandParams);
    modeSelectClusterInteractionInfoMap.put("changeToMode", modeSelectchangeToModeInteractionInfo);
    commandMap.put("modeSelect", modeSelectClusterInteractionInfoMap);
    Map<String, InteractionInfo> doorLockClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> doorLocklockDoorCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocklockDoorpinCodeCommandParameterInfo =
        new CommandParameterInfo("pinCode", Optional.class, byte[].class);
    doorLocklockDoorCommandParams.put("pinCode", doorLocklockDoorpinCodeCommandParameterInfo);

    InteractionInfo doorLocklockDoorInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .lockDoor(
                      (DefaultClusterCallback) callback,
                      (Optional<byte[]>) commandArguments.get("pinCode"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLocklockDoorCommandParams);
    doorLockClusterInteractionInfoMap.put("lockDoor", doorLocklockDoorInteractionInfo);
    Map<String, CommandParameterInfo> doorLockunlockDoorCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockunlockDoorpinCodeCommandParameterInfo =
        new CommandParameterInfo("pinCode", Optional.class, byte[].class);
    doorLockunlockDoorCommandParams.put("pinCode", doorLockunlockDoorpinCodeCommandParameterInfo);

    InteractionInfo doorLockunlockDoorInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .unlockDoor(
                      (DefaultClusterCallback) callback,
                      (Optional<byte[]>) commandArguments.get("pinCode"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockunlockDoorCommandParams);
    doorLockClusterInteractionInfoMap.put("unlockDoor", doorLockunlockDoorInteractionInfo);
    Map<String, CommandParameterInfo> doorLockunlockWithTimeoutCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockunlockWithTimeouttimeoutCommandParameterInfo =
        new CommandParameterInfo("timeout", Integer.class, Integer.class);
    doorLockunlockWithTimeoutCommandParams.put(
        "timeout", doorLockunlockWithTimeouttimeoutCommandParameterInfo);

    CommandParameterInfo doorLockunlockWithTimeoutpinCodeCommandParameterInfo =
        new CommandParameterInfo("pinCode", Optional.class, byte[].class);
    doorLockunlockWithTimeoutCommandParams.put(
        "pinCode", doorLockunlockWithTimeoutpinCodeCommandParameterInfo);

    InteractionInfo doorLockunlockWithTimeoutInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .unlockWithTimeout(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("timeout"),
                      (Optional<byte[]>) commandArguments.get("pinCode"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockunlockWithTimeoutCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "unlockWithTimeout", doorLockunlockWithTimeoutInteractionInfo);
    Map<String, CommandParameterInfo> doorLocksetWeekDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocksetWeekDayScheduleweekDayIndexCommandParameterInfo =
        new CommandParameterInfo("weekDayIndex", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "weekDayIndex", doorLocksetWeekDayScheduleweekDayIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "userIndex", doorLocksetWeekDayScheduleuserIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDayScheduledaysMaskCommandParameterInfo =
        new CommandParameterInfo("daysMask", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "daysMask", doorLocksetWeekDayScheduledaysMaskCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDaySchedulestartHourCommandParameterInfo =
        new CommandParameterInfo("startHour", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "startHour", doorLocksetWeekDaySchedulestartHourCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDaySchedulestartMinuteCommandParameterInfo =
        new CommandParameterInfo("startMinute", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "startMinute", doorLocksetWeekDaySchedulestartMinuteCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDayScheduleendHourCommandParameterInfo =
        new CommandParameterInfo("endHour", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "endHour", doorLocksetWeekDayScheduleendHourCommandParameterInfo);

    CommandParameterInfo doorLocksetWeekDayScheduleendMinuteCommandParameterInfo =
        new CommandParameterInfo("endMinute", Integer.class, Integer.class);
    doorLocksetWeekDayScheduleCommandParams.put(
        "endMinute", doorLocksetWeekDayScheduleendMinuteCommandParameterInfo);

    InteractionInfo doorLocksetWeekDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .setWeekDaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("weekDayIndex"),
                      (Integer) commandArguments.get("userIndex"),
                      (Integer) commandArguments.get("daysMask"),
                      (Integer) commandArguments.get("startHour"),
                      (Integer) commandArguments.get("startMinute"),
                      (Integer) commandArguments.get("endHour"),
                      (Integer) commandArguments.get("endMinute"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLocksetWeekDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "setWeekDaySchedule", doorLocksetWeekDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockgetWeekDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockgetWeekDayScheduleweekDayIndexCommandParameterInfo =
        new CommandParameterInfo("weekDayIndex", Integer.class, Integer.class);
    doorLockgetWeekDayScheduleCommandParams.put(
        "weekDayIndex", doorLockgetWeekDayScheduleweekDayIndexCommandParameterInfo);

    CommandParameterInfo doorLockgetWeekDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockgetWeekDayScheduleCommandParams.put(
        "userIndex", doorLockgetWeekDayScheduleuserIndexCommandParameterInfo);

    InteractionInfo doorLockgetWeekDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .getWeekDaySchedule(
                      (ChipClusters.DoorLockCluster.GetWeekDayScheduleResponseCallback) callback,
                      (Integer) commandArguments.get("weekDayIndex"),
                      (Integer) commandArguments.get("userIndex"));
            },
            () -> new DelegatedGetWeekDayScheduleResponseCallback(),
            doorLockgetWeekDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "getWeekDaySchedule", doorLockgetWeekDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockclearWeekDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockclearWeekDayScheduleweekDayIndexCommandParameterInfo =
        new CommandParameterInfo("weekDayIndex", Integer.class, Integer.class);
    doorLockclearWeekDayScheduleCommandParams.put(
        "weekDayIndex", doorLockclearWeekDayScheduleweekDayIndexCommandParameterInfo);

    CommandParameterInfo doorLockclearWeekDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockclearWeekDayScheduleCommandParams.put(
        "userIndex", doorLockclearWeekDayScheduleuserIndexCommandParameterInfo);

    InteractionInfo doorLockclearWeekDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .clearWeekDaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("weekDayIndex"),
                      (Integer) commandArguments.get("userIndex"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockclearWeekDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "clearWeekDaySchedule", doorLockclearWeekDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLocksetYearDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocksetYearDayScheduleyearDayIndexCommandParameterInfo =
        new CommandParameterInfo("yearDayIndex", Integer.class, Integer.class);
    doorLocksetYearDayScheduleCommandParams.put(
        "yearDayIndex", doorLocksetYearDayScheduleyearDayIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetYearDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLocksetYearDayScheduleCommandParams.put(
        "userIndex", doorLocksetYearDayScheduleuserIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetYearDaySchedulelocalStartTimeCommandParameterInfo =
        new CommandParameterInfo("localStartTime", Long.class, Long.class);
    doorLocksetYearDayScheduleCommandParams.put(
        "localStartTime", doorLocksetYearDaySchedulelocalStartTimeCommandParameterInfo);

    CommandParameterInfo doorLocksetYearDaySchedulelocalEndTimeCommandParameterInfo =
        new CommandParameterInfo("localEndTime", Long.class, Long.class);
    doorLocksetYearDayScheduleCommandParams.put(
        "localEndTime", doorLocksetYearDaySchedulelocalEndTimeCommandParameterInfo);

    InteractionInfo doorLocksetYearDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .setYearDaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("yearDayIndex"),
                      (Integer) commandArguments.get("userIndex"),
                      (Long) commandArguments.get("localStartTime"),
                      (Long) commandArguments.get("localEndTime"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLocksetYearDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "setYearDaySchedule", doorLocksetYearDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockgetYearDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockgetYearDayScheduleyearDayIndexCommandParameterInfo =
        new CommandParameterInfo("yearDayIndex", Integer.class, Integer.class);
    doorLockgetYearDayScheduleCommandParams.put(
        "yearDayIndex", doorLockgetYearDayScheduleyearDayIndexCommandParameterInfo);

    CommandParameterInfo doorLockgetYearDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockgetYearDayScheduleCommandParams.put(
        "userIndex", doorLockgetYearDayScheduleuserIndexCommandParameterInfo);

    InteractionInfo doorLockgetYearDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .getYearDaySchedule(
                      (ChipClusters.DoorLockCluster.GetYearDayScheduleResponseCallback) callback,
                      (Integer) commandArguments.get("yearDayIndex"),
                      (Integer) commandArguments.get("userIndex"));
            },
            () -> new DelegatedGetYearDayScheduleResponseCallback(),
            doorLockgetYearDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "getYearDaySchedule", doorLockgetYearDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockclearYearDayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockclearYearDayScheduleyearDayIndexCommandParameterInfo =
        new CommandParameterInfo("yearDayIndex", Integer.class, Integer.class);
    doorLockclearYearDayScheduleCommandParams.put(
        "yearDayIndex", doorLockclearYearDayScheduleyearDayIndexCommandParameterInfo);

    CommandParameterInfo doorLockclearYearDayScheduleuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockclearYearDayScheduleCommandParams.put(
        "userIndex", doorLockclearYearDayScheduleuserIndexCommandParameterInfo);

    InteractionInfo doorLockclearYearDayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .clearYearDaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("yearDayIndex"),
                      (Integer) commandArguments.get("userIndex"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockclearYearDayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "clearYearDaySchedule", doorLockclearYearDayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLocksetHolidayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocksetHolidayScheduleholidayIndexCommandParameterInfo =
        new CommandParameterInfo("holidayIndex", Integer.class, Integer.class);
    doorLocksetHolidayScheduleCommandParams.put(
        "holidayIndex", doorLocksetHolidayScheduleholidayIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetHolidaySchedulelocalStartTimeCommandParameterInfo =
        new CommandParameterInfo("localStartTime", Long.class, Long.class);
    doorLocksetHolidayScheduleCommandParams.put(
        "localStartTime", doorLocksetHolidaySchedulelocalStartTimeCommandParameterInfo);

    CommandParameterInfo doorLocksetHolidaySchedulelocalEndTimeCommandParameterInfo =
        new CommandParameterInfo("localEndTime", Long.class, Long.class);
    doorLocksetHolidayScheduleCommandParams.put(
        "localEndTime", doorLocksetHolidaySchedulelocalEndTimeCommandParameterInfo);

    CommandParameterInfo doorLocksetHolidayScheduleoperatingModeCommandParameterInfo =
        new CommandParameterInfo("operatingMode", Integer.class, Integer.class);
    doorLocksetHolidayScheduleCommandParams.put(
        "operatingMode", doorLocksetHolidayScheduleoperatingModeCommandParameterInfo);

    InteractionInfo doorLocksetHolidayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .setHolidaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("holidayIndex"),
                      (Long) commandArguments.get("localStartTime"),
                      (Long) commandArguments.get("localEndTime"),
                      (Integer) commandArguments.get("operatingMode"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLocksetHolidayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "setHolidaySchedule", doorLocksetHolidayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockgetHolidayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockgetHolidayScheduleholidayIndexCommandParameterInfo =
        new CommandParameterInfo("holidayIndex", Integer.class, Integer.class);
    doorLockgetHolidayScheduleCommandParams.put(
        "holidayIndex", doorLockgetHolidayScheduleholidayIndexCommandParameterInfo);

    InteractionInfo doorLockgetHolidayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .getHolidaySchedule(
                      (ChipClusters.DoorLockCluster.GetHolidayScheduleResponseCallback) callback,
                      (Integer) commandArguments.get("holidayIndex"));
            },
            () -> new DelegatedGetHolidayScheduleResponseCallback(),
            doorLockgetHolidayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "getHolidaySchedule", doorLockgetHolidayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLockclearHolidayScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockclearHolidayScheduleholidayIndexCommandParameterInfo =
        new CommandParameterInfo("holidayIndex", Integer.class, Integer.class);
    doorLockclearHolidayScheduleCommandParams.put(
        "holidayIndex", doorLockclearHolidayScheduleholidayIndexCommandParameterInfo);

    InteractionInfo doorLockclearHolidayScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .clearHolidaySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("holidayIndex"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockclearHolidayScheduleCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "clearHolidaySchedule", doorLockclearHolidayScheduleInteractionInfo);
    Map<String, CommandParameterInfo> doorLocksetUserCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocksetUseroperationTypeCommandParameterInfo =
        new CommandParameterInfo("operationType", Integer.class, Integer.class);
    doorLocksetUserCommandParams.put(
        "operationType", doorLocksetUseroperationTypeCommandParameterInfo);

    CommandParameterInfo doorLocksetUseruserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLocksetUserCommandParams.put("userIndex", doorLocksetUseruserIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetUseruserNameCommandParameterInfo =
        new CommandParameterInfo("userName", String.class, String.class);
    doorLocksetUserCommandParams.put("userName", doorLocksetUseruserNameCommandParameterInfo);

    CommandParameterInfo doorLocksetUseruserUniqueIdCommandParameterInfo =
        new CommandParameterInfo("userUniqueId", Long.class, Long.class);
    doorLocksetUserCommandParams.put(
        "userUniqueId", doorLocksetUseruserUniqueIdCommandParameterInfo);

    CommandParameterInfo doorLocksetUseruserStatusCommandParameterInfo =
        new CommandParameterInfo("userStatus", Integer.class, Integer.class);
    doorLocksetUserCommandParams.put("userStatus", doorLocksetUseruserStatusCommandParameterInfo);

    CommandParameterInfo doorLocksetUseruserTypeCommandParameterInfo =
        new CommandParameterInfo("userType", Integer.class, Integer.class);
    doorLocksetUserCommandParams.put("userType", doorLocksetUseruserTypeCommandParameterInfo);

    CommandParameterInfo doorLocksetUsercredentialRuleCommandParameterInfo =
        new CommandParameterInfo("credentialRule", Integer.class, Integer.class);
    doorLocksetUserCommandParams.put(
        "credentialRule", doorLocksetUsercredentialRuleCommandParameterInfo);

    InteractionInfo doorLocksetUserInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .setUser(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("operationType"),
                      (Integer) commandArguments.get("userIndex"),
                      (String) commandArguments.get("userName"),
                      (Long) commandArguments.get("userUniqueId"),
                      (Integer) commandArguments.get("userStatus"),
                      (Integer) commandArguments.get("userType"),
                      (Integer) commandArguments.get("credentialRule"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLocksetUserCommandParams);
    doorLockClusterInteractionInfoMap.put("setUser", doorLocksetUserInteractionInfo);
    Map<String, CommandParameterInfo> doorLockgetUserCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockgetUseruserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockgetUserCommandParams.put("userIndex", doorLockgetUseruserIndexCommandParameterInfo);

    InteractionInfo doorLockgetUserInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .getUser(
                      (ChipClusters.DoorLockCluster.GetUserResponseCallback) callback,
                      (Integer) commandArguments.get("userIndex"));
            },
            () -> new DelegatedGetUserResponseCallback(),
            doorLockgetUserCommandParams);
    doorLockClusterInteractionInfoMap.put("getUser", doorLockgetUserInteractionInfo);
    Map<String, CommandParameterInfo> doorLockclearUserCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLockclearUseruserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLockclearUserCommandParams.put("userIndex", doorLockclearUseruserIndexCommandParameterInfo);

    InteractionInfo doorLockclearUserInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .clearUser(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("userIndex"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockclearUserCommandParams);
    doorLockClusterInteractionInfoMap.put("clearUser", doorLockclearUserInteractionInfo);
    Map<String, CommandParameterInfo> doorLocksetCredentialCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo doorLocksetCredentialoperationTypeCommandParameterInfo =
        new CommandParameterInfo("operationType", Integer.class, Integer.class);
    doorLocksetCredentialCommandParams.put(
        "operationType", doorLocksetCredentialoperationTypeCommandParameterInfo);

    CommandParameterInfo doorLocksetCredentialcredentialDataCommandParameterInfo =
        new CommandParameterInfo("credentialData", byte[].class, byte[].class);
    doorLocksetCredentialCommandParams.put(
        "credentialData", doorLocksetCredentialcredentialDataCommandParameterInfo);

    CommandParameterInfo doorLocksetCredentialuserIndexCommandParameterInfo =
        new CommandParameterInfo("userIndex", Integer.class, Integer.class);
    doorLocksetCredentialCommandParams.put(
        "userIndex", doorLocksetCredentialuserIndexCommandParameterInfo);

    CommandParameterInfo doorLocksetCredentialuserStatusCommandParameterInfo =
        new CommandParameterInfo("userStatus", Integer.class, Integer.class);
    doorLocksetCredentialCommandParams.put(
        "userStatus", doorLocksetCredentialuserStatusCommandParameterInfo);

    CommandParameterInfo doorLocksetCredentialuserTypeCommandParameterInfo =
        new CommandParameterInfo("userType", Integer.class, Integer.class);
    doorLocksetCredentialCommandParams.put(
        "userType", doorLocksetCredentialuserTypeCommandParameterInfo);

    InteractionInfo doorLocksetCredentialInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .setCredential(
                      (ChipClusters.DoorLockCluster.SetCredentialResponseCallback) callback,
                      (Integer) commandArguments.get("operationType"),
                      (ChipStructs.DoorLockClusterDlCredential) commandArguments.get("credential"),
                      (byte[]) commandArguments.get("credentialData"),
                      (Integer) commandArguments.get("userIndex"),
                      (Integer) commandArguments.get("userStatus"),
                      (Integer) commandArguments.get("userType"),
                      10000);
            },
            () -> new DelegatedSetCredentialResponseCallback(),
            doorLocksetCredentialCommandParams);
    doorLockClusterInteractionInfoMap.put("setCredential", doorLocksetCredentialInteractionInfo);
    Map<String, CommandParameterInfo> doorLockgetCredentialStatusCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo doorLockgetCredentialStatusInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .getCredentialStatus(
                      (ChipClusters.DoorLockCluster.GetCredentialStatusResponseCallback) callback,
                      (ChipStructs.DoorLockClusterDlCredential) commandArguments.get("credential"));
            },
            () -> new DelegatedGetCredentialStatusResponseCallback(),
            doorLockgetCredentialStatusCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "getCredentialStatus", doorLockgetCredentialStatusInteractionInfo);
    Map<String, CommandParameterInfo> doorLockclearCredentialCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo doorLockclearCredentialInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.DoorLockCluster) cluster)
                  .clearCredential(
                      (DefaultClusterCallback) callback,
                      (ChipStructs.DoorLockClusterDlCredential) commandArguments.get("credential"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            doorLockclearCredentialCommandParams);
    doorLockClusterInteractionInfoMap.put(
        "clearCredential", doorLockclearCredentialInteractionInfo);
    commandMap.put("doorLock", doorLockClusterInteractionInfoMap);
    Map<String, InteractionInfo> windowCoveringClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> windowCoveringupOrOpenCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo windowCoveringupOrOpenInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .upOrOpen((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringupOrOpenCommandParams);
    windowCoveringClusterInteractionInfoMap.put("upOrOpen", windowCoveringupOrOpenInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringdownOrCloseCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo windowCoveringdownOrCloseInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .downOrClose((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringdownOrCloseCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "downOrClose", windowCoveringdownOrCloseInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringstopMotionCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo windowCoveringstopMotionInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .stopMotion((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringstopMotionCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "stopMotion", windowCoveringstopMotionInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringgoToLiftValueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo windowCoveringgoToLiftValueliftValueCommandParameterInfo =
        new CommandParameterInfo("liftValue", Integer.class, Integer.class);
    windowCoveringgoToLiftValueCommandParams.put(
        "liftValue", windowCoveringgoToLiftValueliftValueCommandParameterInfo);

    InteractionInfo windowCoveringgoToLiftValueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .goToLiftValue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("liftValue"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringgoToLiftValueCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "goToLiftValue", windowCoveringgoToLiftValueInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringgoToLiftPercentageCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        windowCoveringgoToLiftPercentageliftPercent100thsValueCommandParameterInfo =
            new CommandParameterInfo("liftPercent100thsValue", Integer.class, Integer.class);
    windowCoveringgoToLiftPercentageCommandParams.put(
        "liftPercent100thsValue",
        windowCoveringgoToLiftPercentageliftPercent100thsValueCommandParameterInfo);

    InteractionInfo windowCoveringgoToLiftPercentageInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .goToLiftPercentage(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("liftPercent100thsValue"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringgoToLiftPercentageCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "goToLiftPercentage", windowCoveringgoToLiftPercentageInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringgoToTiltValueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo windowCoveringgoToTiltValuetiltValueCommandParameterInfo =
        new CommandParameterInfo("tiltValue", Integer.class, Integer.class);
    windowCoveringgoToTiltValueCommandParams.put(
        "tiltValue", windowCoveringgoToTiltValuetiltValueCommandParameterInfo);

    InteractionInfo windowCoveringgoToTiltValueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .goToTiltValue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("tiltValue"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringgoToTiltValueCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "goToTiltValue", windowCoveringgoToTiltValueInteractionInfo);
    Map<String, CommandParameterInfo> windowCoveringgoToTiltPercentageCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        windowCoveringgoToTiltPercentagetiltPercent100thsValueCommandParameterInfo =
            new CommandParameterInfo("tiltPercent100thsValue", Integer.class, Integer.class);
    windowCoveringgoToTiltPercentageCommandParams.put(
        "tiltPercent100thsValue",
        windowCoveringgoToTiltPercentagetiltPercent100thsValueCommandParameterInfo);

    InteractionInfo windowCoveringgoToTiltPercentageInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.WindowCoveringCluster) cluster)
                  .goToTiltPercentage(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("tiltPercent100thsValue"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            windowCoveringgoToTiltPercentageCommandParams);
    windowCoveringClusterInteractionInfoMap.put(
        "goToTiltPercentage", windowCoveringgoToTiltPercentageInteractionInfo);
    commandMap.put("windowCovering", windowCoveringClusterInteractionInfoMap);
    Map<String, InteractionInfo> barrierControlClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> barrierControlbarrierControlGoToPercentCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo barrierControlbarrierControlGoToPercentpercentOpenCommandParameterInfo =
        new CommandParameterInfo("percentOpen", Integer.class, Integer.class);
    barrierControlbarrierControlGoToPercentCommandParams.put(
        "percentOpen", barrierControlbarrierControlGoToPercentpercentOpenCommandParameterInfo);

    InteractionInfo barrierControlbarrierControlGoToPercentInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BarrierControlCluster) cluster)
                  .barrierControlGoToPercent(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("percentOpen"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            barrierControlbarrierControlGoToPercentCommandParams);
    barrierControlClusterInteractionInfoMap.put(
        "barrierControlGoToPercent", barrierControlbarrierControlGoToPercentInteractionInfo);
    Map<String, CommandParameterInfo> barrierControlbarrierControlStopCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo barrierControlbarrierControlStopInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.BarrierControlCluster) cluster)
                  .barrierControlStop((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            barrierControlbarrierControlStopCommandParams);
    barrierControlClusterInteractionInfoMap.put(
        "barrierControlStop", barrierControlbarrierControlStopInteractionInfo);
    commandMap.put("barrierControl", barrierControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> pumpConfigurationAndControlClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put(
        "pumpConfigurationAndControl", pumpConfigurationAndControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> thermostatClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> thermostatsetpointRaiseLowerCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo thermostatsetpointRaiseLowermodeCommandParameterInfo =
        new CommandParameterInfo("mode", Integer.class, Integer.class);
    thermostatsetpointRaiseLowerCommandParams.put(
        "mode", thermostatsetpointRaiseLowermodeCommandParameterInfo);

    CommandParameterInfo thermostatsetpointRaiseLoweramountCommandParameterInfo =
        new CommandParameterInfo("amount", Integer.class, Integer.class);
    thermostatsetpointRaiseLowerCommandParams.put(
        "amount", thermostatsetpointRaiseLoweramountCommandParameterInfo);

    InteractionInfo thermostatsetpointRaiseLowerInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ThermostatCluster) cluster)
                  .setpointRaiseLower(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("mode"),
                      (Integer) commandArguments.get("amount"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            thermostatsetpointRaiseLowerCommandParams);
    thermostatClusterInteractionInfoMap.put(
        "setpointRaiseLower", thermostatsetpointRaiseLowerInteractionInfo);
    Map<String, CommandParameterInfo> thermostatsetWeeklyScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo
        thermostatsetWeeklySchedulenumberOfTransitionsForSequenceCommandParameterInfo =
            new CommandParameterInfo(
                "numberOfTransitionsForSequence", Integer.class, Integer.class);
    thermostatsetWeeklyScheduleCommandParams.put(
        "numberOfTransitionsForSequence",
        thermostatsetWeeklySchedulenumberOfTransitionsForSequenceCommandParameterInfo);

    CommandParameterInfo thermostatsetWeeklyScheduledayOfWeekForSequenceCommandParameterInfo =
        new CommandParameterInfo("dayOfWeekForSequence", Integer.class, Integer.class);
    thermostatsetWeeklyScheduleCommandParams.put(
        "dayOfWeekForSequence",
        thermostatsetWeeklyScheduledayOfWeekForSequenceCommandParameterInfo);

    CommandParameterInfo thermostatsetWeeklySchedulemodeForSequenceCommandParameterInfo =
        new CommandParameterInfo("modeForSequence", Integer.class, Integer.class);
    thermostatsetWeeklyScheduleCommandParams.put(
        "modeForSequence", thermostatsetWeeklySchedulemodeForSequenceCommandParameterInfo);

    InteractionInfo thermostatsetWeeklyScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ThermostatCluster) cluster)
                  .setWeeklySchedule(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("numberOfTransitionsForSequence"),
                      (Integer) commandArguments.get("dayOfWeekForSequence"),
                      (Integer) commandArguments.get("modeForSequence"),
                      (ArrayList<ChipStructs.ThermostatClusterThermostatScheduleTransition>)
                          commandArguments.get("transitions"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            thermostatsetWeeklyScheduleCommandParams);
    thermostatClusterInteractionInfoMap.put(
        "setWeeklySchedule", thermostatsetWeeklyScheduleInteractionInfo);
    Map<String, CommandParameterInfo> thermostatgetWeeklyScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo thermostatgetWeeklyScheduledaysToReturnCommandParameterInfo =
        new CommandParameterInfo("daysToReturn", Integer.class, Integer.class);
    thermostatgetWeeklyScheduleCommandParams.put(
        "daysToReturn", thermostatgetWeeklyScheduledaysToReturnCommandParameterInfo);

    CommandParameterInfo thermostatgetWeeklySchedulemodeToReturnCommandParameterInfo =
        new CommandParameterInfo("modeToReturn", Integer.class, Integer.class);
    thermostatgetWeeklyScheduleCommandParams.put(
        "modeToReturn", thermostatgetWeeklySchedulemodeToReturnCommandParameterInfo);

    InteractionInfo thermostatgetWeeklyScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ThermostatCluster) cluster)
                  .getWeeklySchedule(
                      (ChipClusters.ThermostatCluster.GetWeeklyScheduleResponseCallback) callback,
                      (Integer) commandArguments.get("daysToReturn"),
                      (Integer) commandArguments.get("modeToReturn"));
            },
            () -> new DelegatedGetWeeklyScheduleResponseCallback(),
            thermostatgetWeeklyScheduleCommandParams);
    thermostatClusterInteractionInfoMap.put(
        "getWeeklySchedule", thermostatgetWeeklyScheduleInteractionInfo);
    Map<String, CommandParameterInfo> thermostatclearWeeklyScheduleCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo thermostatclearWeeklyScheduleInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ThermostatCluster) cluster)
                  .clearWeeklySchedule((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            thermostatclearWeeklyScheduleCommandParams);
    thermostatClusterInteractionInfoMap.put(
        "clearWeeklySchedule", thermostatclearWeeklyScheduleInteractionInfo);
    commandMap.put("thermostat", thermostatClusterInteractionInfoMap);
    Map<String, InteractionInfo> fanControlClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("fanControl", fanControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> thermostatUserInterfaceConfigurationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put(
        "thermostatUserInterfaceConfiguration",
        thermostatUserInterfaceConfigurationClusterInteractionInfoMap);
    Map<String, InteractionInfo> colorControlClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> colorControlmoveToHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveToHuehueCommandParameterInfo =
        new CommandParameterInfo("hue", Integer.class, Integer.class);
    colorControlmoveToHueCommandParams.put("hue", colorControlmoveToHuehueCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHuedirectionCommandParameterInfo =
        new CommandParameterInfo("direction", Integer.class, Integer.class);
    colorControlmoveToHueCommandParams.put(
        "direction", colorControlmoveToHuedirectionCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHuetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlmoveToHueCommandParams.put(
        "transitionTime", colorControlmoveToHuetransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveToHueCommandParams.put(
        "optionsMask", colorControlmoveToHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveToHueCommandParams.put(
        "optionsOverride", colorControlmoveToHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveToHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveToHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("hue"),
                      (Integer) commandArguments.get("direction"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveToHueCommandParams);
    colorControlClusterInteractionInfoMap.put("moveToHue", colorControlmoveToHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveHuemoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    colorControlmoveHueCommandParams.put(
        "moveMode", colorControlmoveHuemoveModeCommandParameterInfo);

    CommandParameterInfo colorControlmoveHuerateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    colorControlmoveHueCommandParams.put("rate", colorControlmoveHuerateCommandParameterInfo);

    CommandParameterInfo colorControlmoveHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveHueCommandParams.put(
        "optionsMask", colorControlmoveHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveHueCommandParams.put(
        "optionsOverride", colorControlmoveHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveHueCommandParams);
    colorControlClusterInteractionInfoMap.put("moveHue", colorControlmoveHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlstepHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlstepHuestepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    colorControlstepHueCommandParams.put(
        "stepMode", colorControlstepHuestepModeCommandParameterInfo);

    CommandParameterInfo colorControlstepHuestepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    colorControlstepHueCommandParams.put(
        "stepSize", colorControlstepHuestepSizeCommandParameterInfo);

    CommandParameterInfo colorControlstepHuetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlstepHueCommandParams.put(
        "transitionTime", colorControlstepHuetransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlstepHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlstepHueCommandParams.put(
        "optionsMask", colorControlstepHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlstepHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlstepHueCommandParams.put(
        "optionsOverride", colorControlstepHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlstepHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .stepHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlstepHueCommandParams);
    colorControlClusterInteractionInfoMap.put("stepHue", colorControlstepHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveToSaturationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveToSaturationsaturationCommandParameterInfo =
        new CommandParameterInfo("saturation", Integer.class, Integer.class);
    colorControlmoveToSaturationCommandParams.put(
        "saturation", colorControlmoveToSaturationsaturationCommandParameterInfo);

    CommandParameterInfo colorControlmoveToSaturationtransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlmoveToSaturationCommandParams.put(
        "transitionTime", colorControlmoveToSaturationtransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlmoveToSaturationoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveToSaturationCommandParams.put(
        "optionsMask", colorControlmoveToSaturationoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveToSaturationoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveToSaturationCommandParams.put(
        "optionsOverride", colorControlmoveToSaturationoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveToSaturationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveToSaturation(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("saturation"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveToSaturationCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveToSaturation", colorControlmoveToSaturationInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveSaturationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveSaturationmoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    colorControlmoveSaturationCommandParams.put(
        "moveMode", colorControlmoveSaturationmoveModeCommandParameterInfo);

    CommandParameterInfo colorControlmoveSaturationrateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    colorControlmoveSaturationCommandParams.put(
        "rate", colorControlmoveSaturationrateCommandParameterInfo);

    CommandParameterInfo colorControlmoveSaturationoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveSaturationCommandParams.put(
        "optionsMask", colorControlmoveSaturationoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveSaturationoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveSaturationCommandParams.put(
        "optionsOverride", colorControlmoveSaturationoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveSaturationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveSaturation(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveSaturationCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveSaturation", colorControlmoveSaturationInteractionInfo);
    Map<String, CommandParameterInfo> colorControlstepSaturationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlstepSaturationstepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    colorControlstepSaturationCommandParams.put(
        "stepMode", colorControlstepSaturationstepModeCommandParameterInfo);

    CommandParameterInfo colorControlstepSaturationstepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    colorControlstepSaturationCommandParams.put(
        "stepSize", colorControlstepSaturationstepSizeCommandParameterInfo);

    CommandParameterInfo colorControlstepSaturationtransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlstepSaturationCommandParams.put(
        "transitionTime", colorControlstepSaturationtransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlstepSaturationoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlstepSaturationCommandParams.put(
        "optionsMask", colorControlstepSaturationoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlstepSaturationoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlstepSaturationCommandParams.put(
        "optionsOverride", colorControlstepSaturationoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlstepSaturationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .stepSaturation(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlstepSaturationCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "stepSaturation", colorControlstepSaturationInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveToHueAndSaturationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveToHueAndSaturationhueCommandParameterInfo =
        new CommandParameterInfo("hue", Integer.class, Integer.class);
    colorControlmoveToHueAndSaturationCommandParams.put(
        "hue", colorControlmoveToHueAndSaturationhueCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueAndSaturationsaturationCommandParameterInfo =
        new CommandParameterInfo("saturation", Integer.class, Integer.class);
    colorControlmoveToHueAndSaturationCommandParams.put(
        "saturation", colorControlmoveToHueAndSaturationsaturationCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueAndSaturationtransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlmoveToHueAndSaturationCommandParams.put(
        "transitionTime", colorControlmoveToHueAndSaturationtransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueAndSaturationoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveToHueAndSaturationCommandParams.put(
        "optionsMask", colorControlmoveToHueAndSaturationoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveToHueAndSaturationoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveToHueAndSaturationCommandParams.put(
        "optionsOverride", colorControlmoveToHueAndSaturationoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveToHueAndSaturationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveToHueAndSaturation(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("hue"),
                      (Integer) commandArguments.get("saturation"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveToHueAndSaturationCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveToHueAndSaturation", colorControlmoveToHueAndSaturationInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveToColorCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveToColorcolorXCommandParameterInfo =
        new CommandParameterInfo("colorX", Integer.class, Integer.class);
    colorControlmoveToColorCommandParams.put(
        "colorX", colorControlmoveToColorcolorXCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColorcolorYCommandParameterInfo =
        new CommandParameterInfo("colorY", Integer.class, Integer.class);
    colorControlmoveToColorCommandParams.put(
        "colorY", colorControlmoveToColorcolorYCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColortransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlmoveToColorCommandParams.put(
        "transitionTime", colorControlmoveToColortransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColoroptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveToColorCommandParams.put(
        "optionsMask", colorControlmoveToColoroptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColoroptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveToColorCommandParams.put(
        "optionsOverride", colorControlmoveToColoroptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveToColorInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveToColor(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("colorX"),
                      (Integer) commandArguments.get("colorY"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveToColorCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveToColor", colorControlmoveToColorInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveColorCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveColorrateXCommandParameterInfo =
        new CommandParameterInfo("rateX", Integer.class, Integer.class);
    colorControlmoveColorCommandParams.put("rateX", colorControlmoveColorrateXCommandParameterInfo);

    CommandParameterInfo colorControlmoveColorrateYCommandParameterInfo =
        new CommandParameterInfo("rateY", Integer.class, Integer.class);
    colorControlmoveColorCommandParams.put("rateY", colorControlmoveColorrateYCommandParameterInfo);

    CommandParameterInfo colorControlmoveColoroptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveColorCommandParams.put(
        "optionsMask", colorControlmoveColoroptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveColoroptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveColorCommandParams.put(
        "optionsOverride", colorControlmoveColoroptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveColorInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveColor(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("rateX"),
                      (Integer) commandArguments.get("rateY"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveColorCommandParams);
    colorControlClusterInteractionInfoMap.put("moveColor", colorControlmoveColorInteractionInfo);
    Map<String, CommandParameterInfo> colorControlstepColorCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlstepColorstepXCommandParameterInfo =
        new CommandParameterInfo("stepX", Integer.class, Integer.class);
    colorControlstepColorCommandParams.put("stepX", colorControlstepColorstepXCommandParameterInfo);

    CommandParameterInfo colorControlstepColorstepYCommandParameterInfo =
        new CommandParameterInfo("stepY", Integer.class, Integer.class);
    colorControlstepColorCommandParams.put("stepY", colorControlstepColorstepYCommandParameterInfo);

    CommandParameterInfo colorControlstepColortransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlstepColorCommandParams.put(
        "transitionTime", colorControlstepColortransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlstepColoroptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlstepColorCommandParams.put(
        "optionsMask", colorControlstepColoroptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlstepColoroptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlstepColorCommandParams.put(
        "optionsOverride", colorControlstepColoroptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlstepColorInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .stepColor(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepX"),
                      (Integer) commandArguments.get("stepY"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlstepColorCommandParams);
    colorControlClusterInteractionInfoMap.put("stepColor", colorControlstepColorInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveToColorTemperatureCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveToColorTemperaturecolorTemperatureCommandParameterInfo =
        new CommandParameterInfo("colorTemperature", Integer.class, Integer.class);
    colorControlmoveToColorTemperatureCommandParams.put(
        "colorTemperature", colorControlmoveToColorTemperaturecolorTemperatureCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColorTemperaturetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlmoveToColorTemperatureCommandParams.put(
        "transitionTime", colorControlmoveToColorTemperaturetransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColorTemperatureoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveToColorTemperatureCommandParams.put(
        "optionsMask", colorControlmoveToColorTemperatureoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveToColorTemperatureoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveToColorTemperatureCommandParams.put(
        "optionsOverride", colorControlmoveToColorTemperatureoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveToColorTemperatureInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveToColorTemperature(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("colorTemperature"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveToColorTemperatureCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveToColorTemperature", colorControlmoveToColorTemperatureInteractionInfo);
    Map<String, CommandParameterInfo> colorControlenhancedMoveToHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlenhancedMoveToHueenhancedHueCommandParameterInfo =
        new CommandParameterInfo("enhancedHue", Integer.class, Integer.class);
    colorControlenhancedMoveToHueCommandParams.put(
        "enhancedHue", colorControlenhancedMoveToHueenhancedHueCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHuedirectionCommandParameterInfo =
        new CommandParameterInfo("direction", Integer.class, Integer.class);
    colorControlenhancedMoveToHueCommandParams.put(
        "direction", colorControlenhancedMoveToHuedirectionCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHuetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlenhancedMoveToHueCommandParams.put(
        "transitionTime", colorControlenhancedMoveToHuetransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlenhancedMoveToHueCommandParams.put(
        "optionsMask", colorControlenhancedMoveToHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlenhancedMoveToHueCommandParams.put(
        "optionsOverride", colorControlenhancedMoveToHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlenhancedMoveToHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .enhancedMoveToHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("enhancedHue"),
                      (Integer) commandArguments.get("direction"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlenhancedMoveToHueCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "enhancedMoveToHue", colorControlenhancedMoveToHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlenhancedMoveHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlenhancedMoveHuemoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    colorControlenhancedMoveHueCommandParams.put(
        "moveMode", colorControlenhancedMoveHuemoveModeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveHuerateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    colorControlenhancedMoveHueCommandParams.put(
        "rate", colorControlenhancedMoveHuerateCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlenhancedMoveHueCommandParams.put(
        "optionsMask", colorControlenhancedMoveHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlenhancedMoveHueCommandParams.put(
        "optionsOverride", colorControlenhancedMoveHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlenhancedMoveHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .enhancedMoveHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlenhancedMoveHueCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "enhancedMoveHue", colorControlenhancedMoveHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlenhancedStepHueCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlenhancedStepHuestepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    colorControlenhancedStepHueCommandParams.put(
        "stepMode", colorControlenhancedStepHuestepModeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedStepHuestepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    colorControlenhancedStepHueCommandParams.put(
        "stepSize", colorControlenhancedStepHuestepSizeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedStepHuetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlenhancedStepHueCommandParams.put(
        "transitionTime", colorControlenhancedStepHuetransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedStepHueoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlenhancedStepHueCommandParams.put(
        "optionsMask", colorControlenhancedStepHueoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlenhancedStepHueoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlenhancedStepHueCommandParams.put(
        "optionsOverride", colorControlenhancedStepHueoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlenhancedStepHueInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .enhancedStepHue(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlenhancedStepHueCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "enhancedStepHue", colorControlenhancedStepHueInteractionInfo);
    Map<String, CommandParameterInfo> colorControlenhancedMoveToHueAndSaturationCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlenhancedMoveToHueAndSaturationenhancedHueCommandParameterInfo =
        new CommandParameterInfo("enhancedHue", Integer.class, Integer.class);
    colorControlenhancedMoveToHueAndSaturationCommandParams.put(
        "enhancedHue", colorControlenhancedMoveToHueAndSaturationenhancedHueCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHueAndSaturationsaturationCommandParameterInfo =
        new CommandParameterInfo("saturation", Integer.class, Integer.class);
    colorControlenhancedMoveToHueAndSaturationCommandParams.put(
        "saturation", colorControlenhancedMoveToHueAndSaturationsaturationCommandParameterInfo);

    CommandParameterInfo
        colorControlenhancedMoveToHueAndSaturationtransitionTimeCommandParameterInfo =
            new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlenhancedMoveToHueAndSaturationCommandParams.put(
        "transitionTime",
        colorControlenhancedMoveToHueAndSaturationtransitionTimeCommandParameterInfo);

    CommandParameterInfo colorControlenhancedMoveToHueAndSaturationoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlenhancedMoveToHueAndSaturationCommandParams.put(
        "optionsMask", colorControlenhancedMoveToHueAndSaturationoptionsMaskCommandParameterInfo);

    CommandParameterInfo
        colorControlenhancedMoveToHueAndSaturationoptionsOverrideCommandParameterInfo =
            new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlenhancedMoveToHueAndSaturationCommandParams.put(
        "optionsOverride",
        colorControlenhancedMoveToHueAndSaturationoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlenhancedMoveToHueAndSaturationInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .enhancedMoveToHueAndSaturation(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("enhancedHue"),
                      (Integer) commandArguments.get("saturation"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlenhancedMoveToHueAndSaturationCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "enhancedMoveToHueAndSaturation",
        colorControlenhancedMoveToHueAndSaturationInteractionInfo);
    Map<String, CommandParameterInfo> colorControlcolorLoopSetCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlcolorLoopSetupdateFlagsCommandParameterInfo =
        new CommandParameterInfo("updateFlags", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "updateFlags", colorControlcolorLoopSetupdateFlagsCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSetactionCommandParameterInfo =
        new CommandParameterInfo("action", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "action", colorControlcolorLoopSetactionCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSetdirectionCommandParameterInfo =
        new CommandParameterInfo("direction", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "direction", colorControlcolorLoopSetdirectionCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSettimeCommandParameterInfo =
        new CommandParameterInfo("time", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "time", colorControlcolorLoopSettimeCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSetstartHueCommandParameterInfo =
        new CommandParameterInfo("startHue", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "startHue", colorControlcolorLoopSetstartHueCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSetoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "optionsMask", colorControlcolorLoopSetoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlcolorLoopSetoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlcolorLoopSetCommandParams.put(
        "optionsOverride", colorControlcolorLoopSetoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlcolorLoopSetInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .colorLoopSet(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("updateFlags"),
                      (Integer) commandArguments.get("action"),
                      (Integer) commandArguments.get("direction"),
                      (Integer) commandArguments.get("time"),
                      (Integer) commandArguments.get("startHue"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlcolorLoopSetCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "colorLoopSet", colorControlcolorLoopSetInteractionInfo);
    Map<String, CommandParameterInfo> colorControlstopMoveStepCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlstopMoveStepoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlstopMoveStepCommandParams.put(
        "optionsMask", colorControlstopMoveStepoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlstopMoveStepoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlstopMoveStepCommandParams.put(
        "optionsOverride", colorControlstopMoveStepoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlstopMoveStepInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .stopMoveStep(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlstopMoveStepCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "stopMoveStep", colorControlstopMoveStepInteractionInfo);
    Map<String, CommandParameterInfo> colorControlmoveColorTemperatureCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlmoveColorTemperaturemoveModeCommandParameterInfo =
        new CommandParameterInfo("moveMode", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "moveMode", colorControlmoveColorTemperaturemoveModeCommandParameterInfo);

    CommandParameterInfo colorControlmoveColorTemperaturerateCommandParameterInfo =
        new CommandParameterInfo("rate", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "rate", colorControlmoveColorTemperaturerateCommandParameterInfo);

    CommandParameterInfo
        colorControlmoveColorTemperaturecolorTemperatureMinimumMiredsCommandParameterInfo =
            new CommandParameterInfo("colorTemperatureMinimumMireds", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "colorTemperatureMinimumMireds",
        colorControlmoveColorTemperaturecolorTemperatureMinimumMiredsCommandParameterInfo);

    CommandParameterInfo
        colorControlmoveColorTemperaturecolorTemperatureMaximumMiredsCommandParameterInfo =
            new CommandParameterInfo("colorTemperatureMaximumMireds", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "colorTemperatureMaximumMireds",
        colorControlmoveColorTemperaturecolorTemperatureMaximumMiredsCommandParameterInfo);

    CommandParameterInfo colorControlmoveColorTemperatureoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "optionsMask", colorControlmoveColorTemperatureoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlmoveColorTemperatureoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlmoveColorTemperatureCommandParams.put(
        "optionsOverride", colorControlmoveColorTemperatureoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlmoveColorTemperatureInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .moveColorTemperature(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("moveMode"),
                      (Integer) commandArguments.get("rate"),
                      (Integer) commandArguments.get("colorTemperatureMinimumMireds"),
                      (Integer) commandArguments.get("colorTemperatureMaximumMireds"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlmoveColorTemperatureCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "moveColorTemperature", colorControlmoveColorTemperatureInteractionInfo);
    Map<String, CommandParameterInfo> colorControlstepColorTemperatureCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo colorControlstepColorTemperaturestepModeCommandParameterInfo =
        new CommandParameterInfo("stepMode", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "stepMode", colorControlstepColorTemperaturestepModeCommandParameterInfo);

    CommandParameterInfo colorControlstepColorTemperaturestepSizeCommandParameterInfo =
        new CommandParameterInfo("stepSize", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "stepSize", colorControlstepColorTemperaturestepSizeCommandParameterInfo);

    CommandParameterInfo colorControlstepColorTemperaturetransitionTimeCommandParameterInfo =
        new CommandParameterInfo("transitionTime", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "transitionTime", colorControlstepColorTemperaturetransitionTimeCommandParameterInfo);

    CommandParameterInfo
        colorControlstepColorTemperaturecolorTemperatureMinimumMiredsCommandParameterInfo =
            new CommandParameterInfo("colorTemperatureMinimumMireds", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "colorTemperatureMinimumMireds",
        colorControlstepColorTemperaturecolorTemperatureMinimumMiredsCommandParameterInfo);

    CommandParameterInfo
        colorControlstepColorTemperaturecolorTemperatureMaximumMiredsCommandParameterInfo =
            new CommandParameterInfo("colorTemperatureMaximumMireds", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "colorTemperatureMaximumMireds",
        colorControlstepColorTemperaturecolorTemperatureMaximumMiredsCommandParameterInfo);

    CommandParameterInfo colorControlstepColorTemperatureoptionsMaskCommandParameterInfo =
        new CommandParameterInfo("optionsMask", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "optionsMask", colorControlstepColorTemperatureoptionsMaskCommandParameterInfo);

    CommandParameterInfo colorControlstepColorTemperatureoptionsOverrideCommandParameterInfo =
        new CommandParameterInfo("optionsOverride", Integer.class, Integer.class);
    colorControlstepColorTemperatureCommandParams.put(
        "optionsOverride", colorControlstepColorTemperatureoptionsOverrideCommandParameterInfo);

    InteractionInfo colorControlstepColorTemperatureInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ColorControlCluster) cluster)
                  .stepColorTemperature(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("stepMode"),
                      (Integer) commandArguments.get("stepSize"),
                      (Integer) commandArguments.get("transitionTime"),
                      (Integer) commandArguments.get("colorTemperatureMinimumMireds"),
                      (Integer) commandArguments.get("colorTemperatureMaximumMireds"),
                      (Integer) commandArguments.get("optionsMask"),
                      (Integer) commandArguments.get("optionsOverride"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            colorControlstepColorTemperatureCommandParams);
    colorControlClusterInteractionInfoMap.put(
        "stepColorTemperature", colorControlstepColorTemperatureInteractionInfo);
    commandMap.put("colorControl", colorControlClusterInteractionInfoMap);
    Map<String, InteractionInfo> ballastConfigurationClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("ballastConfiguration", ballastConfigurationClusterInteractionInfoMap);
    Map<String, InteractionInfo> illuminanceMeasurementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("illuminanceMeasurement", illuminanceMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> temperatureMeasurementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("temperatureMeasurement", temperatureMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> pressureMeasurementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("pressureMeasurement", pressureMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> flowMeasurementClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("flowMeasurement", flowMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> relativeHumidityMeasurementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put(
        "relativeHumidityMeasurement", relativeHumidityMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> occupancySensingClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("occupancySensing", occupancySensingClusterInteractionInfoMap);
    Map<String, InteractionInfo> wakeOnLanClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("wakeOnLan", wakeOnLanClusterInteractionInfoMap);
    Map<String, InteractionInfo> channelClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> channelchangeChannelCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo channelchangeChannelmatchCommandParameterInfo =
        new CommandParameterInfo("match", String.class, String.class);
    channelchangeChannelCommandParams.put("match", channelchangeChannelmatchCommandParameterInfo);

    InteractionInfo channelchangeChannelInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ChannelCluster) cluster)
                  .changeChannel(
                      (ChipClusters.ChannelCluster.ChangeChannelResponseCallback) callback,
                      (String) commandArguments.get("match"));
            },
            () -> new DelegatedChangeChannelResponseCallback(),
            channelchangeChannelCommandParams);
    channelClusterInteractionInfoMap.put("changeChannel", channelchangeChannelInteractionInfo);
    Map<String, CommandParameterInfo> channelchangeChannelByNumberCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo channelchangeChannelByNumbermajorNumberCommandParameterInfo =
        new CommandParameterInfo("majorNumber", Integer.class, Integer.class);
    channelchangeChannelByNumberCommandParams.put(
        "majorNumber", channelchangeChannelByNumbermajorNumberCommandParameterInfo);

    CommandParameterInfo channelchangeChannelByNumberminorNumberCommandParameterInfo =
        new CommandParameterInfo("minorNumber", Integer.class, Integer.class);
    channelchangeChannelByNumberCommandParams.put(
        "minorNumber", channelchangeChannelByNumberminorNumberCommandParameterInfo);

    InteractionInfo channelchangeChannelByNumberInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ChannelCluster) cluster)
                  .changeChannelByNumber(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("majorNumber"),
                      (Integer) commandArguments.get("minorNumber"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            channelchangeChannelByNumberCommandParams);
    channelClusterInteractionInfoMap.put(
        "changeChannelByNumber", channelchangeChannelByNumberInteractionInfo);
    Map<String, CommandParameterInfo> channelskipChannelCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo channelskipChannelcountCommandParameterInfo =
        new CommandParameterInfo("count", Integer.class, Integer.class);
    channelskipChannelCommandParams.put("count", channelskipChannelcountCommandParameterInfo);

    InteractionInfo channelskipChannelInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ChannelCluster) cluster)
                  .skipChannel(
                      (DefaultClusterCallback) callback, (Integer) commandArguments.get("count"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            channelskipChannelCommandParams);
    channelClusterInteractionInfoMap.put("skipChannel", channelskipChannelInteractionInfo);
    commandMap.put("channel", channelClusterInteractionInfoMap);
    Map<String, InteractionInfo> targetNavigatorClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> targetNavigatornavigateTargetCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo targetNavigatornavigateTargettargetCommandParameterInfo =
        new CommandParameterInfo("target", Integer.class, Integer.class);
    targetNavigatornavigateTargetCommandParams.put(
        "target", targetNavigatornavigateTargettargetCommandParameterInfo);

    CommandParameterInfo targetNavigatornavigateTargetdataCommandParameterInfo =
        new CommandParameterInfo("data", Optional.class, String.class);
    targetNavigatornavigateTargetCommandParams.put(
        "data", targetNavigatornavigateTargetdataCommandParameterInfo);

    InteractionInfo targetNavigatornavigateTargetInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.TargetNavigatorCluster) cluster)
                  .navigateTarget(
                      (ChipClusters.TargetNavigatorCluster.NavigateTargetResponseCallback) callback,
                      (Integer) commandArguments.get("target"),
                      (Optional<String>) commandArguments.get("data"));
            },
            () -> new DelegatedNavigateTargetResponseCallback(),
            targetNavigatornavigateTargetCommandParams);
    targetNavigatorClusterInteractionInfoMap.put(
        "navigateTarget", targetNavigatornavigateTargetInteractionInfo);
    commandMap.put("targetNavigator", targetNavigatorClusterInteractionInfoMap);
    Map<String, InteractionInfo> mediaPlaybackClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> mediaPlaybackplayCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackplayInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .play((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybackplayCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("play", mediaPlaybackplayInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackpauseCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackpauseInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .pause((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybackpauseCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("pause", mediaPlaybackpauseInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackstopPlaybackCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackstopPlaybackInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .stopPlayback(
                      (ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybackstopPlaybackCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put(
        "stopPlayback", mediaPlaybackstopPlaybackInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackstartOverCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackstartOverInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .startOver((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybackstartOverCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("startOver", mediaPlaybackstartOverInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackpreviousCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackpreviousInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .previous((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybackpreviousCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("previous", mediaPlaybackpreviousInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybacknextCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybacknextInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .next((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybacknextCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("next", mediaPlaybacknextInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackrewindCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackrewindInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .rewind((ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybackrewindCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("rewind", mediaPlaybackrewindInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackfastForwardCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaPlaybackfastForwardInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .fastForward(
                      (ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback);
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybackfastForwardCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put(
        "fastForward", mediaPlaybackfastForwardInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackskipForwardCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo mediaPlaybackskipForwarddeltaPositionMillisecondsCommandParameterInfo =
        new CommandParameterInfo("deltaPositionMilliseconds", Long.class, Long.class);
    mediaPlaybackskipForwardCommandParams.put(
        "deltaPositionMilliseconds",
        mediaPlaybackskipForwarddeltaPositionMillisecondsCommandParameterInfo);

    InteractionInfo mediaPlaybackskipForwardInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .skipForward(
                      (ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback,
                      (Long) commandArguments.get("deltaPositionMilliseconds"));
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybackskipForwardCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put(
        "skipForward", mediaPlaybackskipForwardInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackskipBackwardCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo mediaPlaybackskipBackwarddeltaPositionMillisecondsCommandParameterInfo =
        new CommandParameterInfo("deltaPositionMilliseconds", Long.class, Long.class);
    mediaPlaybackskipBackwardCommandParams.put(
        "deltaPositionMilliseconds",
        mediaPlaybackskipBackwarddeltaPositionMillisecondsCommandParameterInfo);

    InteractionInfo mediaPlaybackskipBackwardInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .skipBackward(
                      (ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback,
                      (Long) commandArguments.get("deltaPositionMilliseconds"));
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybackskipBackwardCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put(
        "skipBackward", mediaPlaybackskipBackwardInteractionInfo);
    Map<String, CommandParameterInfo> mediaPlaybackseekCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo mediaPlaybackseekpositionCommandParameterInfo =
        new CommandParameterInfo("position", Long.class, Long.class);
    mediaPlaybackseekCommandParams.put("position", mediaPlaybackseekpositionCommandParameterInfo);

    InteractionInfo mediaPlaybackseekInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaPlaybackCluster) cluster)
                  .seek(
                      (ChipClusters.MediaPlaybackCluster.PlaybackResponseCallback) callback,
                      (Long) commandArguments.get("position"));
            },
            () -> new DelegatedPlaybackResponseCallback(),
            mediaPlaybackseekCommandParams);
    mediaPlaybackClusterInteractionInfoMap.put("seek", mediaPlaybackseekInteractionInfo);
    commandMap.put("mediaPlayback", mediaPlaybackClusterInteractionInfoMap);
    Map<String, InteractionInfo> mediaInputClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> mediaInputselectInputCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo mediaInputselectInputindexCommandParameterInfo =
        new CommandParameterInfo("index", Integer.class, Integer.class);
    mediaInputselectInputCommandParams.put("index", mediaInputselectInputindexCommandParameterInfo);

    InteractionInfo mediaInputselectInputInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaInputCluster) cluster)
                  .selectInput(
                      (DefaultClusterCallback) callback, (Integer) commandArguments.get("index"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            mediaInputselectInputCommandParams);
    mediaInputClusterInteractionInfoMap.put("selectInput", mediaInputselectInputInteractionInfo);
    Map<String, CommandParameterInfo> mediaInputshowInputStatusCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaInputshowInputStatusInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaInputCluster) cluster)
                  .showInputStatus((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            mediaInputshowInputStatusCommandParams);
    mediaInputClusterInteractionInfoMap.put(
        "showInputStatus", mediaInputshowInputStatusInteractionInfo);
    Map<String, CommandParameterInfo> mediaInputhideInputStatusCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo mediaInputhideInputStatusInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaInputCluster) cluster)
                  .hideInputStatus((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            mediaInputhideInputStatusCommandParams);
    mediaInputClusterInteractionInfoMap.put(
        "hideInputStatus", mediaInputhideInputStatusInteractionInfo);
    Map<String, CommandParameterInfo> mediaInputrenameInputCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo mediaInputrenameInputindexCommandParameterInfo =
        new CommandParameterInfo("index", Integer.class, Integer.class);
    mediaInputrenameInputCommandParams.put("index", mediaInputrenameInputindexCommandParameterInfo);

    CommandParameterInfo mediaInputrenameInputnameCommandParameterInfo =
        new CommandParameterInfo("name", String.class, String.class);
    mediaInputrenameInputCommandParams.put("name", mediaInputrenameInputnameCommandParameterInfo);

    InteractionInfo mediaInputrenameInputInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.MediaInputCluster) cluster)
                  .renameInput(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("index"),
                      (String) commandArguments.get("name"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            mediaInputrenameInputCommandParams);
    mediaInputClusterInteractionInfoMap.put("renameInput", mediaInputrenameInputInteractionInfo);
    commandMap.put("mediaInput", mediaInputClusterInteractionInfoMap);
    Map<String, InteractionInfo> lowPowerClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> lowPowersleepCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo lowPowersleepInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.LowPowerCluster) cluster).sleep((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            lowPowersleepCommandParams);
    lowPowerClusterInteractionInfoMap.put("sleep", lowPowersleepInteractionInfo);
    commandMap.put("lowPower", lowPowerClusterInteractionInfoMap);
    Map<String, InteractionInfo> keypadInputClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> keypadInputsendKeyCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo keypadInputsendKeykeyCodeCommandParameterInfo =
        new CommandParameterInfo("keyCode", Integer.class, Integer.class);
    keypadInputsendKeyCommandParams.put("keyCode", keypadInputsendKeykeyCodeCommandParameterInfo);

    InteractionInfo keypadInputsendKeyInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.KeypadInputCluster) cluster)
                  .sendKey(
                      (ChipClusters.KeypadInputCluster.SendKeyResponseCallback) callback,
                      (Integer) commandArguments.get("keyCode"));
            },
            () -> new DelegatedSendKeyResponseCallback(),
            keypadInputsendKeyCommandParams);
    keypadInputClusterInteractionInfoMap.put("sendKey", keypadInputsendKeyInteractionInfo);
    commandMap.put("keypadInput", keypadInputClusterInteractionInfoMap);
    Map<String, InteractionInfo> contentLauncherClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> contentLauncherlaunchContentCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo contentLauncherlaunchContentautoPlayCommandParameterInfo =
        new CommandParameterInfo("autoPlay", Boolean.class, Boolean.class);
    contentLauncherlaunchContentCommandParams.put(
        "autoPlay", contentLauncherlaunchContentautoPlayCommandParameterInfo);

    CommandParameterInfo contentLauncherlaunchContentdataCommandParameterInfo =
        new CommandParameterInfo("data", Optional.class, String.class);
    contentLauncherlaunchContentCommandParams.put(
        "data", contentLauncherlaunchContentdataCommandParameterInfo);

    InteractionInfo contentLauncherlaunchContentInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ContentLauncherCluster) cluster)
                  .launchContent(
                      (ChipClusters.ContentLauncherCluster.LaunchResponseCallback) callback,
                      (ChipStructs.ContentLauncherClusterContentSearch)
                          commandArguments.get("search"),
                      (Boolean) commandArguments.get("autoPlay"),
                      (Optional<String>) commandArguments.get("data"));
            },
            () -> new DelegatedLaunchResponseCallback(),
            contentLauncherlaunchContentCommandParams);
    contentLauncherClusterInteractionInfoMap.put(
        "launchContent", contentLauncherlaunchContentInteractionInfo);
    Map<String, CommandParameterInfo> contentLauncherlaunchURLCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo contentLauncherlaunchURLcontentURLCommandParameterInfo =
        new CommandParameterInfo("contentURL", String.class, String.class);
    contentLauncherlaunchURLCommandParams.put(
        "contentURL", contentLauncherlaunchURLcontentURLCommandParameterInfo);

    CommandParameterInfo contentLauncherlaunchURLdisplayStringCommandParameterInfo =
        new CommandParameterInfo("displayString", Optional.class, String.class);
    contentLauncherlaunchURLCommandParams.put(
        "displayString", contentLauncherlaunchURLdisplayStringCommandParameterInfo);

    InteractionInfo contentLauncherlaunchURLInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ContentLauncherCluster) cluster)
                  .launchURL(
                      (ChipClusters.ContentLauncherCluster.LaunchResponseCallback) callback,
                      (String) commandArguments.get("contentURL"),
                      (Optional<String>) commandArguments.get("displayString"),
                      (Optional<ChipStructs.ContentLauncherClusterBrandingInformation>)
                          commandArguments.get("brandingInformation"));
            },
            () -> new DelegatedLaunchResponseCallback(),
            contentLauncherlaunchURLCommandParams);
    contentLauncherClusterInteractionInfoMap.put(
        "launchURL", contentLauncherlaunchURLInteractionInfo);
    commandMap.put("contentLauncher", contentLauncherClusterInteractionInfoMap);
    Map<String, InteractionInfo> audioOutputClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> audioOutputselectOutputCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo audioOutputselectOutputindexCommandParameterInfo =
        new CommandParameterInfo("index", Integer.class, Integer.class);
    audioOutputselectOutputCommandParams.put(
        "index", audioOutputselectOutputindexCommandParameterInfo);

    InteractionInfo audioOutputselectOutputInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AudioOutputCluster) cluster)
                  .selectOutput(
                      (DefaultClusterCallback) callback, (Integer) commandArguments.get("index"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            audioOutputselectOutputCommandParams);
    audioOutputClusterInteractionInfoMap.put(
        "selectOutput", audioOutputselectOutputInteractionInfo);
    Map<String, CommandParameterInfo> audioOutputrenameOutputCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo audioOutputrenameOutputindexCommandParameterInfo =
        new CommandParameterInfo("index", Integer.class, Integer.class);
    audioOutputrenameOutputCommandParams.put(
        "index", audioOutputrenameOutputindexCommandParameterInfo);

    CommandParameterInfo audioOutputrenameOutputnameCommandParameterInfo =
        new CommandParameterInfo("name", String.class, String.class);
    audioOutputrenameOutputCommandParams.put(
        "name", audioOutputrenameOutputnameCommandParameterInfo);

    InteractionInfo audioOutputrenameOutputInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AudioOutputCluster) cluster)
                  .renameOutput(
                      (DefaultClusterCallback) callback,
                      (Integer) commandArguments.get("index"),
                      (String) commandArguments.get("name"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            audioOutputrenameOutputCommandParams);
    audioOutputClusterInteractionInfoMap.put(
        "renameOutput", audioOutputrenameOutputInteractionInfo);
    commandMap.put("audioOutput", audioOutputClusterInteractionInfoMap);
    Map<String, InteractionInfo> applicationLauncherClusterInteractionInfoMap =
        new LinkedHashMap<>();
    Map<String, CommandParameterInfo> applicationLauncherlaunchAppCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo applicationLauncherlaunchAppdataCommandParameterInfo =
        new CommandParameterInfo("data", Optional.class, byte[].class);
    applicationLauncherlaunchAppCommandParams.put(
        "data", applicationLauncherlaunchAppdataCommandParameterInfo);

    InteractionInfo applicationLauncherlaunchAppInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ApplicationLauncherCluster) cluster)
                  .launchApp(
                      (ChipClusters.ApplicationLauncherCluster.LauncherResponseCallback) callback,
                      (ChipStructs.ApplicationLauncherClusterApplication)
                          commandArguments.get("application"),
                      (Optional<byte[]>) commandArguments.get("data"));
            },
            () -> new DelegatedLauncherResponseCallback(),
            applicationLauncherlaunchAppCommandParams);
    applicationLauncherClusterInteractionInfoMap.put(
        "launchApp", applicationLauncherlaunchAppInteractionInfo);
    Map<String, CommandParameterInfo> applicationLauncherstopAppCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo applicationLauncherstopAppInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ApplicationLauncherCluster) cluster)
                  .stopApp(
                      (ChipClusters.ApplicationLauncherCluster.LauncherResponseCallback) callback,
                      (ChipStructs.ApplicationLauncherClusterApplication)
                          commandArguments.get("application"));
            },
            () -> new DelegatedLauncherResponseCallback(),
            applicationLauncherstopAppCommandParams);
    applicationLauncherClusterInteractionInfoMap.put(
        "stopApp", applicationLauncherstopAppInteractionInfo);
    Map<String, CommandParameterInfo> applicationLauncherhideAppCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo applicationLauncherhideAppInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.ApplicationLauncherCluster) cluster)
                  .hideApp(
                      (ChipClusters.ApplicationLauncherCluster.LauncherResponseCallback) callback,
                      (ChipStructs.ApplicationLauncherClusterApplication)
                          commandArguments.get("application"));
            },
            () -> new DelegatedLauncherResponseCallback(),
            applicationLauncherhideAppCommandParams);
    applicationLauncherClusterInteractionInfoMap.put(
        "hideApp", applicationLauncherhideAppInteractionInfo);
    commandMap.put("applicationLauncher", applicationLauncherClusterInteractionInfoMap);
    Map<String, InteractionInfo> applicationBasicClusterInteractionInfoMap = new LinkedHashMap<>();
    commandMap.put("applicationBasic", applicationBasicClusterInteractionInfoMap);
    Map<String, InteractionInfo> accountLoginClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> accountLogingetSetupPINCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo accountLogingetSetupPINtempAccountIdentifierCommandParameterInfo =
        new CommandParameterInfo("tempAccountIdentifier", String.class, String.class);
    accountLogingetSetupPINCommandParams.put(
        "tempAccountIdentifier", accountLogingetSetupPINtempAccountIdentifierCommandParameterInfo);

    InteractionInfo accountLogingetSetupPINInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AccountLoginCluster) cluster)
                  .getSetupPIN(
                      (ChipClusters.AccountLoginCluster.GetSetupPINResponseCallback) callback,
                      (String) commandArguments.get("tempAccountIdentifier"),
                      10000);
            },
            () -> new DelegatedGetSetupPINResponseCallback(),
            accountLogingetSetupPINCommandParams);
    accountLoginClusterInteractionInfoMap.put(
        "getSetupPIN", accountLogingetSetupPINInteractionInfo);
    Map<String, CommandParameterInfo> accountLoginloginCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo accountLoginlogintempAccountIdentifierCommandParameterInfo =
        new CommandParameterInfo("tempAccountIdentifier", String.class, String.class);
    accountLoginloginCommandParams.put(
        "tempAccountIdentifier", accountLoginlogintempAccountIdentifierCommandParameterInfo);

    CommandParameterInfo accountLoginloginsetupPINCommandParameterInfo =
        new CommandParameterInfo("setupPIN", String.class, String.class);
    accountLoginloginCommandParams.put("setupPIN", accountLoginloginsetupPINCommandParameterInfo);

    InteractionInfo accountLoginloginInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AccountLoginCluster) cluster)
                  .login(
                      (DefaultClusterCallback) callback,
                      (String) commandArguments.get("tempAccountIdentifier"),
                      (String) commandArguments.get("setupPIN"),
                      10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            accountLoginloginCommandParams);
    accountLoginClusterInteractionInfoMap.put("login", accountLoginloginInteractionInfo);
    Map<String, CommandParameterInfo> accountLoginlogoutCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo accountLoginlogoutInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.AccountLoginCluster) cluster)
                  .logout((DefaultClusterCallback) callback, 10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            accountLoginlogoutCommandParams);
    accountLoginClusterInteractionInfoMap.put("logout", accountLoginlogoutInteractionInfo);
    commandMap.put("accountLogin", accountLoginClusterInteractionInfoMap);
    Map<String, InteractionInfo> electricalMeasurementClusterInteractionInfoMap =
        new LinkedHashMap<>();
    commandMap.put("electricalMeasurement", electricalMeasurementClusterInteractionInfoMap);
    Map<String, InteractionInfo> unitTestingClusterInteractionInfoMap = new LinkedHashMap<>();
    Map<String, CommandParameterInfo> unitTestingtestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster).test((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            unitTestingtestCommandParams);
    unitTestingClusterInteractionInfoMap.put("test", unitTestingtestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestNotHandledCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestNotHandledInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testNotHandled((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            unitTestingtestNotHandledCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testNotHandled", unitTestingtestNotHandledInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestSpecificCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestSpecificInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testSpecific(
                      (ChipClusters.UnitTestingCluster.TestSpecificResponseCallback) callback);
            },
            () -> new DelegatedTestSpecificResponseCallback(),
            unitTestingtestSpecificCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testSpecific", unitTestingtestSpecificInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestUnknownCommandCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestUnknownCommandInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testUnknownCommand((DefaultClusterCallback) callback);
            },
            () -> new DelegatedDefaultClusterCallback(),
            unitTestingtestUnknownCommandCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testUnknownCommand", unitTestingtestUnknownCommandInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestAddArgumentsCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestAddArgumentsarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Integer.class, Integer.class);
    unitTestingtestAddArgumentsCommandParams.put(
        "arg1", unitTestingtestAddArgumentsarg1CommandParameterInfo);

    CommandParameterInfo unitTestingtestAddArgumentsarg2CommandParameterInfo =
        new CommandParameterInfo("arg2", Integer.class, Integer.class);
    unitTestingtestAddArgumentsCommandParams.put(
        "arg2", unitTestingtestAddArgumentsarg2CommandParameterInfo);

    InteractionInfo unitTestingtestAddArgumentsInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testAddArguments(
                      (ChipClusters.UnitTestingCluster.TestAddArgumentsResponseCallback) callback,
                      (Integer) commandArguments.get("arg1"),
                      (Integer) commandArguments.get("arg2"));
            },
            () -> new DelegatedTestAddArgumentsResponseCallback(),
            unitTestingtestAddArgumentsCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testAddArguments", unitTestingtestAddArgumentsInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestStructArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestStructArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testStructArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ChipStructs.UnitTestingClusterSimpleStruct) commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            unitTestingtestStructArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testStructArgumentRequest", unitTestingtestStructArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestNestedStructArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestNestedStructArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testNestedStructArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ChipStructs.UnitTestingClusterNestedStruct) commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            unitTestingtestNestedStructArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testNestedStructArgumentRequest",
        unitTestingtestNestedStructArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestListStructArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestListStructArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testListStructArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ArrayList<ChipStructs.UnitTestingClusterSimpleStruct>)
                          commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            unitTestingtestListStructArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testListStructArgumentRequest", unitTestingtestListStructArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestListInt8UArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestListInt8UArgumentRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", ArrayList.class, Object.class);
    unitTestingtestListInt8UArgumentRequestCommandParams.put(
        "arg1", unitTestingtestListInt8UArgumentRequestarg1CommandParameterInfo);

    InteractionInfo unitTestingtestListInt8UArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testListInt8UArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ArrayList<Integer>) commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            unitTestingtestListInt8UArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testListInt8UArgumentRequest", unitTestingtestListInt8UArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestNestedStructListArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestNestedStructListArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testNestedStructListArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ChipStructs.UnitTestingClusterNestedStructList)
                          commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            unitTestingtestNestedStructListArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testNestedStructListArgumentRequest",
        unitTestingtestNestedStructListArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo>
        unitTestingtestListNestedStructListArgumentRequestCommandParams =
            new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtestListNestedStructListArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testListNestedStructListArgumentRequest(
                      (ChipClusters.UnitTestingCluster.BooleanResponseCallback) callback,
                      (ArrayList<ChipStructs.UnitTestingClusterNestedStructList>)
                          commandArguments.get("arg1"));
            },
            () -> new DelegatedBooleanResponseCallback(),
            unitTestingtestListNestedStructListArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testListNestedStructListArgumentRequest",
        unitTestingtestListNestedStructListArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestListInt8UReverseRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestListInt8UReverseRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", ArrayList.class, Object.class);
    unitTestingtestListInt8UReverseRequestCommandParams.put(
        "arg1", unitTestingtestListInt8UReverseRequestarg1CommandParameterInfo);

    InteractionInfo unitTestingtestListInt8UReverseRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testListInt8UReverseRequest(
                      (ChipClusters.UnitTestingCluster.TestListInt8UReverseResponseCallback)
                          callback,
                      (ArrayList<Integer>) commandArguments.get("arg1"));
            },
            () -> new DelegatedTestListInt8UReverseResponseCallback(),
            unitTestingtestListInt8UReverseRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testListInt8UReverseRequest", unitTestingtestListInt8UReverseRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestEnumsRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestEnumsRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Integer.class, Integer.class);
    unitTestingtestEnumsRequestCommandParams.put(
        "arg1", unitTestingtestEnumsRequestarg1CommandParameterInfo);

    CommandParameterInfo unitTestingtestEnumsRequestarg2CommandParameterInfo =
        new CommandParameterInfo("arg2", Integer.class, Integer.class);
    unitTestingtestEnumsRequestCommandParams.put(
        "arg2", unitTestingtestEnumsRequestarg2CommandParameterInfo);

    InteractionInfo unitTestingtestEnumsRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testEnumsRequest(
                      (ChipClusters.UnitTestingCluster.TestEnumsResponseCallback) callback,
                      (Integer) commandArguments.get("arg1"),
                      (Integer) commandArguments.get("arg2"));
            },
            () -> new DelegatedTestEnumsResponseCallback(),
            unitTestingtestEnumsRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testEnumsRequest", unitTestingtestEnumsRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestNullableOptionalRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestNullableOptionalRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Optional.class, Integer.class);
    unitTestingtestNullableOptionalRequestCommandParams.put(
        "arg1", unitTestingtestNullableOptionalRequestarg1CommandParameterInfo);

    InteractionInfo unitTestingtestNullableOptionalRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testNullableOptionalRequest(
                      (ChipClusters.UnitTestingCluster.TestNullableOptionalResponseCallback)
                          callback,
                      (Optional<Integer>) commandArguments.get("arg1"));
            },
            () -> new DelegatedTestNullableOptionalResponseCallback(),
            unitTestingtestNullableOptionalRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testNullableOptionalRequest", unitTestingtestNullableOptionalRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingsimpleStructEchoRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingsimpleStructEchoRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .simpleStructEchoRequest(
                      (ChipClusters.UnitTestingCluster.SimpleStructResponseCallback) callback,
                      (ChipStructs.UnitTestingClusterSimpleStruct) commandArguments.get("arg1"));
            },
            () -> new DelegatedSimpleStructResponseCallback(),
            unitTestingsimpleStructEchoRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "simpleStructEchoRequest", unitTestingsimpleStructEchoRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtimedInvokeRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    InteractionInfo unitTestingtimedInvokeRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .timedInvokeRequest((DefaultClusterCallback) callback, 10000);
            },
            () -> new DelegatedDefaultClusterCallback(),
            unitTestingtimedInvokeRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "timedInvokeRequest", unitTestingtimedInvokeRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestSimpleOptionalArgumentRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestSimpleOptionalArgumentRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Optional.class, Boolean.class);
    unitTestingtestSimpleOptionalArgumentRequestCommandParams.put(
        "arg1", unitTestingtestSimpleOptionalArgumentRequestarg1CommandParameterInfo);

    InteractionInfo unitTestingtestSimpleOptionalArgumentRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testSimpleOptionalArgumentRequest(
                      (DefaultClusterCallback) callback,
                      (Optional<Boolean>) commandArguments.get("arg1"));
            },
            () -> new DelegatedDefaultClusterCallback(),
            unitTestingtestSimpleOptionalArgumentRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testSimpleOptionalArgumentRequest",
        unitTestingtestSimpleOptionalArgumentRequestInteractionInfo);
    Map<String, CommandParameterInfo> unitTestingtestEmitTestEventRequestCommandParams =
        new LinkedHashMap<String, CommandParameterInfo>();
    CommandParameterInfo unitTestingtestEmitTestEventRequestarg1CommandParameterInfo =
        new CommandParameterInfo("arg1", Integer.class, Integer.class);
    unitTestingtestEmitTestEventRequestCommandParams.put(
        "arg1", unitTestingtestEmitTestEventRequestarg1CommandParameterInfo);

    CommandParameterInfo unitTestingtestEmitTestEventRequestarg2CommandParameterInfo =
        new CommandParameterInfo("arg2", Integer.class, Integer.class);
    unitTestingtestEmitTestEventRequestCommandParams.put(
        "arg2", unitTestingtestEmitTestEventRequestarg2CommandParameterInfo);

    CommandParameterInfo unitTestingtestEmitTestEventRequestarg3CommandParameterInfo =
        new CommandParameterInfo("arg3", Boolean.class, Boolean.class);
    unitTestingtestEmitTestEventRequestCommandParams.put(
        "arg3", unitTestingtestEmitTestEventRequestarg3CommandParameterInfo);

    InteractionInfo unitTestingtestEmitTestEventRequestInteractionInfo =
        new InteractionInfo(
            (cluster, callback, commandArguments) -> {
              ((ChipClusters.UnitTestingCluster) cluster)
                  .testEmitTestEventRequest(
                      (ChipClusters.UnitTestingCluster.TestEmitTestEventResponseCallback) callback,
                      (Integer) commandArguments.get("arg1"),
                      (Integer) commandArguments.get("arg2"),
                      (Boolean) commandArguments.get("arg3"));
            },
            () -> new DelegatedTestEmitTestEventResponseCallback(),
            unitTestingtestEmitTestEventRequestCommandParams);
    unitTestingClusterInteractionInfoMap.put(
        "testEmitTestEventRequest", unitTestingtestEmitTestEventRequestInteractionInfo);
    commandMap.put("unitTesting", unitTestingClusterInteractionInfoMap);
    return commandMap;
  }
}
