void capability_discoverer::handle_extension_id_message(int wiimote_number, checked_array<const u8> data, dolphiimote_callbacks callbacks)
  {
    u8 error_bit = reader.read_error_bit(data);
    checked_array<const u8> extension_id = data.sub_array(7, 6);

    if(error_bit == 0 && data.valid())
    {
      wiimote_states[wiimote_number].extension_id = read_extension_id(extension_id);
      wiimote_states[wiimote_number].enabled_capabilities |= wiimote_capabilities::Extension;
    }
    else
    {
      wiimote_states[wiimote_number].extension_id = 0;
      wiimote_states[wiimote_number].enabled_capabilities &= ~wiimote_capabilities::Extension;
    }
    update_extension_type_from_id(wiimote_number);
    dispatch_capabilities_changed(wiimote_number, callbacks);
	
	if (wiimote_states[wiimote_number].extension_type == wiimote_extensions::BalanceBoard) {
		reader.read(wiimote_number, 0xA40024, 16, std::bind(&capability_discoverer::handle_balanceboard_calibration1, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
		reader.read(wiimote_number, 0xA40024+16, 8, std::bind(&capability_discoverer::handle_balanceboard_calibration2, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
	}
	if (wiimote_states[wiimote_number].extension_type == wiimote_extensions::Nunchuck) {
		reader.read(wiimote_number, 0xA40020, 16, std::bind(&capability_discoverer::handle_balanceboard_calibration1, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
	}
	if (wiimote_states[wiimote_number].extension_type == wiimote_extensions::ClassicController || wiimote_states[wiimote_number].extension_type == wiimote_extensions::ClassicControllerPro) {
		reader.read(wiimote_number, 0xA40020, 16, std::bind(&capability_discoverer::handle_balanceboard_calibration1, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
	}
  }
  void capability_discoverer::handle_balanceboard_calibration2(int wiimote_number, checked_array<const u8> data, dolphiimote_callbacks callbacks)
  {
	  u8 error_bit = reader.read_error_bit(data);
	  checked_array<const u8> calib = data.sub_array(7, 8);

	  wiimote_states[wiimote_number].calibrations.balance_board.kg34.top_right = calib[0] << 8 | calib[1];
	  wiimote_states[wiimote_number].calibrations.balance_board.kg34.bottom_right = calib[2] << 8 | calib[3];
	  wiimote_states[wiimote_number].calibrations.balance_board.kg34.top_left = calib[4] << 8 | calib[5];
	  wiimote_states[wiimote_number].calibrations.balance_board.kg34.bottom_left = calib[6] << 8 | calib[7];
  }
    void data_reporter::handle_data_reporting(dolphiimote_callbacks &callbacks, int wiimote_number, u8 reporting_mode, checked_array<const u8> data)
    {
      dolphiimote_wiimote_data wiimote_data = { 0 };

      retrieve_standard_data(reporting_mode, wiimote_states[wiimote_number], data, wiimote_data);

      if(reporting_mode_extension_data_offset.find(reporting_mode) != reporting_mode_extension_data_offset.end())
      {
        retrieve_extension_data(wiimote_number,
                                wiimote_states[wiimote_number],
                                data.sub_array(reporting_mode_extension_data_offset[reporting_mode].offset,
                                               reporting_mode_extension_data_offset[reporting_mode].size),
                                wiimote_data);
      }

      if(callbacks.data_received != nullptr)
        callbacks.data_received(wiimote_number, &wiimote_data, callbacks.userdata);
    }
  void capability_discoverer::handle_status_report(int wiimote_number, checked_array<const u8> data)
  {
    if(data.size() < 5)
      return;

    u8 flags = data[4];

    bool battery_low = flags & 0x01;
    bool extension_controller_connected = flags & 0x02;
    bool speaker_enabled = flags & 0x04;
    bool ir_camera_enabled = flags & 0x08;

    bool led_1 = flags & 0x10;
    bool led_2 = flags & 0x20;
    bool led_3 = flags & 0x40;
    bool led_4 = flags & 0x80;

    bool capabilities_changed = false;

    handle_extension_controller_changed(flags & 0x02, wiimote_number, capabilities_changed);

    if(capabilities_changed)
      dispatch_capabilities_changed(wiimote_number, callbacks);
  }
  void capability_discoverer::handle_nunchuck_calibration(int wiimote_number, checked_array<const u8> data, dolphiimote_callbacks callbacks)
  {
	  u8 error_bit = reader.read_error_bit(data);
	  checked_array<const u8> calib = data.sub_array(7, 16);
  }