/** {@inheritDoc} */
  @Override
  public void handleApplicationCommandRequest(
      SerialMessage serialMessage, int offset, int endpoint) {
    logger.debug("NODE {}: Received Thermostat Setpoint Request", this.getNode().getNodeId());
    int command = serialMessage.getMessagePayloadByte(offset);
    switch (command) {
      case THERMOSTAT_SETPOINT_SET:
      case THERMOSTAT_SETPOINT_GET:
      case THERMOSTAT_SETPOINT_SUPPORTED_GET:
        logger.warn("NODE {}: Command {} not implemented.", this.getNode().getNodeId(), command);
        return;
      case THERMOSTAT_SETPOINT_SUPPORTED_REPORT:
        logger.debug(
            "NODE {}: Process Thermostat Supported Setpoint Report", this.getNode().getNodeId());

        int payloadLength = serialMessage.getMessagePayload().length;

        for (int i = offset + 1; i < payloadLength; ++i) {
          int bitMask = serialMessage.getMessagePayloadByte(i);
          for (int bit = 0; bit < 8; ++bit) {
            if ((bitMask & (1 << bit)) == 0) continue;

            int index = ((i - (offset + 1)) * 8) + bit;
            if (index >= SetpointType.values().length) continue;

            // (n)th bit is set. n is the index for the setpoint type enumeration.
            SetpointType setpointTypeToAdd = SetpointType.getSetpointType(index);

            if (setpointTypeToAdd == null) {
              logger.warn(
                  "NODE {}: Unknown Setpoint Type = {}, ignoring report.",
                  this.getNode().getNodeId(),
                  index);
              return;
            }

            this.setpointTypes.add(setpointTypeToAdd);
            logger.debug(
                "NODE {}: Added setpoint type {} {}",
                this.getNode().getNodeId(),
                setpointTypeToAdd.getLabel(),
                index);
          }
        }

        this.getNode().advanceNodeStage(NodeStage.DYNAMIC);
        break;
      case THERMOSTAT_SETPOINT_REPORT:
        logger.trace("NODE {}: Process Thermostat Setpoint Report", this.getNode().getNodeId());
        processThermostatSetpointReport(serialMessage, offset, endpoint);

        if (this.getNode().getNodeStage() != NodeStage.DONE)
          this.getNode().advanceNodeStage(NodeStage.DONE);

        break;
      default:
        logger.warn(
            "NODE {}: Unsupported Command {} for command class {} ({}).",
            this.getNode().getNodeId(),
            command,
            this.getCommandClass().getLabel(),
            this.getCommandClass().getKey());
    }
  }