@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
	private boolean internalCreateBond(final boolean ensure) {
		final BluetoothDevice device = bluetoothDevice;
		if (device == null)
			return false;

		if (ensure)
			log(Log.VERBOSE, () -> "Ensuring bonding...");
		else
			log(Log.VERBOSE, () -> "Starting bonding...");

		// Warning: The check below only ensures that the bond information is present on the
		//          Android side, not on both. If the bond information has been remove from the
		//          peripheral side, the code below will notify bonding as success, but in fact the
		//          link will not be encrypted! Currently there is no way to ensure that the link
		//          is secure.
		//          Android, despite reporting bond state as BONDED, creates an unencrypted link
		//          and does not report this as a problem. Calling createBond() on a valid,
		//          encrypted link, to ensure that the link is encrypted, returns false (error).
		//          The same result is returned if only the Android side has bond information,
		//          making both cases indistinguishable.
		//
		// Solution: To make sure that sensitive data are sent only on encrypted link make sure
		//           the characteristic/descriptor is protected and reading/writing to it will
		//           initiate bonding request. To make sure link is encrypted, use ensureBond()
		//           method in BleManager, which will remove old and recreate bonding until this
		//           Android bug is fixed.
		if (!ensure && device.getBondState() == BluetoothDevice.BOND_BONDED) {
			log(Log.WARN, () -> "Bond information present on client, skipping bonding");
			request.notifySuccess(device);
			nextRequest(true);
			return true;
		}
		final boolean result = createBond(device);
		if (ensure && !result) {
			// This will be added as a second.
			// Copy all callbacks from the current request and clear them in the original.
			final Request bond = Request.createBond().setRequestHandler(this);
			// bond.beforeCallback was already fired.
			bond.successCallback = request.successCallback;
			bond.invalidRequestCallback = request.invalidRequestCallback;
			bond.failCallback = request.failCallback;
			bond.internalSuccessCallback = request.internalSuccessCallback;
			bond.internalFailCallback = request.internalFailCallback;
			request.successCallback = null;
			request.invalidRequestCallback = null;
			request.failCallback = null;
			request.internalSuccessCallback = null;
			request.internalFailCallback = null;
			enqueueFirst(bond);
			// This will be added as first.
			enqueueFirst(Request.removeBond().setRequestHandler(this));
			nextRequest(true);
			return true;
		}
		return result;
	}
Returns the value of the server descriptor. For descriptor that are not shared,
the value may be different for each connected device.

@param serverDescriptor The descriptor to get value of.
@return The value.
ble/src/main/java/no/nordicsemi/android/ble/BleManagerHandler.java