diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 7066f79..2b37fef 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1480,6 +1480,7 @@
 
   public final class BluetoothDevice implements android.os.Parcelable {
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean cancelBondProcess();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData);
     method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public byte[] getMetadata(int);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getSimAccessPermission();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isConnected();
@@ -1656,6 +1657,55 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BufferConstraints> CREATOR;
   }
 
+  public final class OobData implements android.os.Parcelable {
+    method @NonNull public static android.bluetooth.OobData.ClassicBuilder createClassicBuilder(@NonNull byte[], @NonNull byte[], @NonNull byte[]);
+    method @NonNull public static android.bluetooth.OobData.LeBuilder createLeBuilder(@NonNull byte[], @NonNull byte[], int);
+    method @NonNull public byte[] getClassOfDevice();
+    method @NonNull public byte[] getClassicLength();
+    method @NonNull public byte[] getConfirmationHash();
+    method @NonNull public byte[] getDeviceAddressWithType();
+    method @Nullable public byte[] getDeviceName();
+    method @Nullable public byte[] getLeAppearance();
+    method @NonNull public int getLeDeviceRole();
+    method @NonNull public int getLeFlags();
+    method @Nullable public byte[] getLeTemporaryKey();
+    method @NonNull public byte[] getRandomizerHash();
+    field public static final int CLASS_OF_DEVICE_OCTETS = 3; // 0x3
+    field public static final int CONFIRMATION_OCTETS = 16; // 0x10
+    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.OobData> CREATOR;
+    field public static final int DEVICE_ADDRESS_OCTETS = 7; // 0x7
+    field public static final int LE_APPEARANCE_OCTETS = 2; // 0x2
+    field public static final int LE_DEVICE_FLAG_OCTETS = 1; // 0x1
+    field public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 3; // 0x3
+    field public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 2; // 0x2
+    field public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 1; // 0x1
+    field public static final int LE_DEVICE_ROLE_OCTETS = 1; // 0x1
+    field public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0; // 0x0
+    field public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 2; // 0x2
+    field public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 1; // 0x1
+    field public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0; // 0x0
+    field public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 3; // 0x3
+    field public static final int LE_FLAG_SIMULTANEOUS_HOST = 4; // 0x4
+    field public static final int LE_TK_OCTETS = 16; // 0x10
+    field public static final int OOB_LENGTH_OCTETS = 2; // 0x2
+    field public static final int RANDOMIZER_OCTETS = 16; // 0x10
+  }
+
+  public static final class OobData.ClassicBuilder {
+    method @NonNull public android.bluetooth.OobData build();
+    method @NonNull public android.bluetooth.OobData.ClassicBuilder setClassOfDevice(@NonNull byte[]);
+    method @NonNull public android.bluetooth.OobData.ClassicBuilder setDeviceName(@NonNull byte[]);
+    method @NonNull public android.bluetooth.OobData.ClassicBuilder setRandomizerHash(@NonNull byte[]);
+  }
+
+  public static final class OobData.LeBuilder {
+    method @NonNull public android.bluetooth.OobData build();
+    method @NonNull public android.bluetooth.OobData.LeBuilder setDeviceName(@NonNull byte[]);
+    method @NonNull public android.bluetooth.OobData.LeBuilder setLeFlags(int);
+    method @NonNull public android.bluetooth.OobData.LeBuilder setLeTemporaryKey(@NonNull byte[]);
+    method @NonNull public android.bluetooth.OobData.LeBuilder setRandomizerHash(@NonNull byte[]);
+  }
+
 }
 
 package android.bluetooth.le {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 89030bc..41bc776 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1279,7 +1279,6 @@
      * the bonding process completes, and its result.
      * <p>Android system services will handle the necessary user interactions
      * to confirm and complete the bonding process.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
      *
      * @param transport The transport to use for the pairing procedure.
      * @return false on immediate error, true if bonding will begin
@@ -1287,8 +1286,9 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     public boolean createBond(int transport) {
-        return createBondOutOfBand(transport, null);
+        return createBondInternal(transport, null, null);
     }
 
     /**
@@ -1302,21 +1302,38 @@
      * <p>Android system services will handle the necessary user interactions
      * to confirm and complete the bonding process.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
+     * <p>There are two possible versions of OOB Data.  This data can come in as
+     * P192 or P256.  This is a reference to the cryptography used to generate the key.
+     * The caller may pass one or both.  If both types of data are passed, then the
+     * P256 data will be preferred, and thus used.
      *
      * @param transport - Transport to use
-     * @param oobData - Out Of Band data
+     * @param remoteP192Data - Out Of Band data (P192) or null
+     * @param remoteP256Data - Out Of Band data (P256) or null
      * @return false on immediate error, true if bonding will begin
      * @hide
      */
-    public boolean createBondOutOfBand(int transport, OobData oobData) {
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public boolean createBondOutOfBand(int transport, @Nullable OobData remoteP192Data,
+            @Nullable OobData remoteP256Data) {
+        if (remoteP192Data == null && remoteP256Data == null) {
+            throw new IllegalArgumentException(
+                "One or both arguments for the OOB data types are required to not be null."
+                + "  Please use createBond() instead if you do not have OOB data to pass.");
+        }
+        return createBondInternal(transport, remoteP192Data, remoteP256Data);
+    }
+
+    private boolean createBondInternal(int transport, @Nullable OobData remoteP192Data,
+            @Nullable OobData remoteP256Data) {
         final IBluetooth service = sService;
         if (service == null) {
             Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
             return false;
         }
         try {
-            return service.createBond(this, transport, oobData);
+            return service.createBond(this, transport, remoteP192Data, remoteP256Data);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
@@ -1347,27 +1364,6 @@
     }
 
     /**
-     * Set the Out Of Band data for a remote device to be used later
-     * in the pairing mechanism. Users can obtain this data through other
-     * trusted channels
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
-     *
-     * @param hash Simple Secure pairing hash
-     * @param randomizer The random key obtained using OOB
-     * @return false on error; true otherwise
-     * @hide
-     */
-    public boolean setDeviceOutOfBandData(byte[] hash, byte[] randomizer) {
-        //TODO(BT)
-      /*
-      try {
-        return sService.setDeviceOutOfBandData(this, hash, randomizer);
-      } catch (RemoteException e) {Log.e(TAG, "", e);} */
-        return false;
-    }
-
-    /**
      * Cancel an in-progress bonding request started with {@link #createBond}.
      *
      * @return true on success, false on error
diff --git a/core/java/android/bluetooth/OobData.java b/core/java/android/bluetooth/OobData.java
index 0d0c6ab..08d694e 100644
--- a/core/java/android/bluetooth/OobData.java
+++ b/core/java/android/bluetooth/OobData.java
@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,88 +16,949 @@
 
 package android.bluetooth;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.util.Preconditions;
+
+import java.lang.IllegalArgumentException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Out Of Band Data for Bluetooth device pairing.
  *
  * <p>This object represents optional data obtained from a remote device through
- * an out-of-band channel (eg. NFC).
+ * an out-of-band channel (eg. NFC, QR).
+ *
+ * <p>References:
+ * NFC AD Forum SSP 1.1 (AD)
+ * {@link https://members.nfc-forum.org//apps/group_public/download.php/24620/NFCForum-AD-BTSSP_1_1.pdf}
+ * Core Specification Supplement (CSS) V9
+ *
+ * <p>There are several BR/EDR Examples
+ *
+ * <p>Negotiated Handover:
+ *   Bluetooth Carrier Configuration Record:
+ *    - OOB Data Length
+ *    - Device Address
+ *    - Class of Device
+ *    - Simple Pairing Hash C
+ *    - Simple Pairing Randomizer R
+ *    - Service Class UUID
+ *    - Bluetooth Local Name
+ *
+ * <p>Static Handover:
+ *   Bluetooth Carrier Configuration Record:
+ *    - OOB Data Length
+ *    - Device Address
+ *    - Class of Device
+ *    - Service Class UUID
+ *    - Bluetooth Local Name
+ *
+ * <p>Simplified Tag Format for Single BT Carrier:
+ *   Bluetooth OOB Data Record:
+ *    - OOB Data Length
+ *    - Device Address
+ *    - Class of Device
+ *    - Service Class UUID
+ *    - Bluetooth Local Name
  *
  * @hide
  */
-public class OobData implements Parcelable {
-    private byte[] mLeBluetoothDeviceAddress;
-    private byte[] mSecurityManagerTk;
-    private byte[] mLeSecureConnectionsConfirmation;
-    private byte[] mLeSecureConnectionsRandom;
+@SystemApi
+public final class OobData implements Parcelable {
 
-    public byte[] getLeBluetoothDeviceAddress() {
-        return mLeBluetoothDeviceAddress;
+    private static final String TAG = "OobData";
+    /** The {@link OobData#mClassicLength} may be. (AD 3.1.1) (CSS 1.6.2) @hide */
+    @SystemApi
+    public static final int OOB_LENGTH_OCTETS = 2;
+    /**
+     * The length for the {@link OobData#mDeviceAddressWithType}(6) and Address Type(1).
+     * (AD 3.1.2) (CSS 1.6.2)
+     * @hide
+     */
+    @SystemApi
+    public static final int DEVICE_ADDRESS_OCTETS = 7;
+    /** The Class of Device is 3 octets. (AD 3.1.3) (CSS 1.6.2) @hide */
+    @SystemApi
+    public static final int CLASS_OF_DEVICE_OCTETS = 3;
+    /** The Confirmation data must be 16 octets. (AD 3.2.2) (CSS 1.6.2) @hide */
+    @SystemApi
+    public static final int CONFIRMATION_OCTETS = 16;
+    /** The Randomizer data must be 16 octets. (AD 3.2.3) (CSS 1.6.2) @hide */
+    @SystemApi
+    public static final int RANDOMIZER_OCTETS = 16;
+    /** The LE Device Role length is 1 octet. (AD 3.3.2) (CSS 1.17) @hide */
+    @SystemApi
+    public static final int LE_DEVICE_ROLE_OCTETS = 1;
+    /** The {@link OobData#mLeTemporaryKey} length. (3.4.1) @hide */
+    @SystemApi
+    public static final int LE_TK_OCTETS = 16;
+    /** The {@link OobData#mLeAppearance} length. (3.4.1) @hide */
+    @SystemApi
+    public static final int LE_APPEARANCE_OCTETS = 2;
+    /** The {@link OobData#mLeFlags} length. (3.4.1) @hide */
+    @SystemApi
+    public static final int LE_DEVICE_FLAG_OCTETS = 1; // 1 octet to hold the 0-4 value.
+
+    // Le Roles
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = { "LE_DEVICE_ROLE_" },
+        value = {
+            LE_DEVICE_ROLE_PERIPHERAL_ONLY,
+            LE_DEVICE_ROLE_CENTRAL_ONLY,
+            LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL,
+            LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL
+        }
+    )
+    public @interface LeRole {}
+
+    /** @hide */
+    @SystemApi
+    public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0x00;
+    /** @hide */
+    @SystemApi
+    public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 0x01;
+    /** @hide */
+    @SystemApi
+    public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 0x02;
+    /** @hide */
+    @SystemApi
+    public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 0x03;
+
+    // Le Flags
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = { "LE_FLAG_" },
+        value = {
+            LE_FLAG_LIMITED_DISCOVERY_MODE,
+            LE_FLAG_GENERAL_DISCOVERY_MODE,
+            LE_FLAG_BREDR_NOT_SUPPORTED,
+            LE_FLAG_SIMULTANEOUS_CONTROLLER,
+            LE_FLAG_SIMULTANEOUS_HOST
+        }
+    )
+    public @interface LeFlag {}
+
+    /** @hide */
+    @SystemApi
+    public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0x00;
+    /** @hide */
+    @SystemApi
+    public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 0x01;
+    /** @hide */
+    @SystemApi
+    public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 0x02;
+    /** @hide */
+    @SystemApi
+    public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 0x03;
+    /** @hide */
+    @SystemApi
+    public static final int LE_FLAG_SIMULTANEOUS_HOST = 0x04;
+
+    /**
+     * Main creation method for creating a Classic version of {@link OobData}.
+     *
+     * <p>This object will allow the caller to call {@link ClassicBuilder#build()}
+     * to build the data object or add any option information to the builder.
+     *
+     * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS} octets
+     * of data. Data is derived from controller/host stack and is required for pairing OOB.
+     * @param classicLength byte array representing the length of data from 8-65535 across 2
+     * octets (0xXXXX).
+     * @param deviceAddressWithType byte array representing the Bluetooth Address of the device
+     * that owns the OOB data. (i.e. the originator) [6 octets]
+     *
+     * @return a Classic Builder instance with all the given data set or null.
+     *
+     * @throws IllegalArgumentException if any of the values fail to be set.
+     * @throws NullPointerException if any argument is null.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public static ClassicBuilder createClassicBuilder(@NonNull byte[] confirmationHash,
+            @NonNull byte[] classicLength, @NonNull byte[] deviceAddressWithType) {
+        return new ClassicBuilder(confirmationHash, classicLength, deviceAddressWithType);
     }
 
     /**
-     * Sets the LE Bluetooth Device Address value to be used during LE pairing.
-     * The value shall be 7 bytes. Please see Bluetooth CSSv6, Part A 1.16 for
-     * a detailed description.
+     * Main creation method for creating a LE version of {@link OobData}.
+     *
+     * <p>This object will allow the caller to call {@link LeBuilder#build()}
+     * to build the data object or add any option information to the builder.
+     *
+     * @param deviceAddressWithType the LE device address plus the address type (7 octets);
+     * not null.
+     * @param leDeviceRole whether the device supports Peripheral, Central,
+     * Both including preference; not null. (1 octet)
+     * @param confirmationHash Array consisting of {@link OobData#CONFIRMATION_OCTETS} octets
+     * of data. Data is derived from controller/host stack and is
+     * required for pairing OOB.
+     *
+     * <p>Possible LE Device Role Values:
+     * 0x00 Only Peripheral supported
+     * 0x01 Only Central supported
+     * 0x02 Central & Peripheral supported; Peripheral Preferred
+     * 0x03 Only peripheral supported; Central Preferred
+     * 0x04 - 0xFF Reserved
+     *
+     * @return a LeBuilder instance with all the given data set or null.
+     *
+     * @throws IllegalArgumentException if any of the values fail to be set.
+     * @throws NullPointerException if any argument is null.
+     *
+     * @hide
      */
-    public void setLeBluetoothDeviceAddress(byte[] leBluetoothDeviceAddress) {
-        mLeBluetoothDeviceAddress = leBluetoothDeviceAddress;
-    }
-
-    public byte[] getSecurityManagerTk() {
-        return mSecurityManagerTk;
+    @NonNull
+    @SystemApi
+    public static LeBuilder createLeBuilder(@NonNull byte[] confirmationHash,
+            @NonNull byte[] deviceAddressWithType, @LeRole int leDeviceRole) {
+        return new LeBuilder(confirmationHash, deviceAddressWithType, leDeviceRole);
     }
 
     /**
-     * Sets the Temporary Key value to be used by the LE Security Manager during
-     * LE pairing. The value shall be 16 bytes. Please see Bluetooth CSSv6,
-     * Part A 1.8 for a detailed description.
+     * Builds an {@link OobData} object and validates that the required combination
+     * of values are present to create the LE specific OobData type.
+     *
+     * @hide
      */
-    public void setSecurityManagerTk(byte[] securityManagerTk) {
-        mSecurityManagerTk = securityManagerTk;
+    @SystemApi
+    public static final class LeBuilder {
+
+        /**
+         * It is recommended that this Hash C is generated anew for each
+         * pairing.
+         *
+         * <p>It should be noted that on passive NFC this isn't possible as the data is static
+         * and immutable.
+         */
+        private byte[] mConfirmationHash = null;
+
+        /**
+         * Optional, but adds more validity to the pairing.
+         *
+         * <p>If not present a value of 0 is assumed.
+         */
+        private byte[] mRandomizerHash = new byte[] {
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        };
+
+        /**
+         * The Bluetooth Device user-friendly name presented over Bluetooth Technology.
+         *
+         * <p>This is the name that may be displayed to the device user as part of the UI.
+         */
+        private byte[] mDeviceName = null;
+
+        /**
+         * Sets the Bluetooth Device name to be used for UI purposes.
+         *
+         * <p>Optional attribute.
+         *
+         * @param deviceName byte array representing the name, may be 0 in length, not null.
+         *
+         * @return {@link OobData#ClassicBuilder}
+         *
+         * @throws NullPointerException if deviceName is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public LeBuilder setDeviceName(@NonNull byte[] deviceName) {
+            Preconditions.checkNotNull(deviceName);
+            this.mDeviceName = deviceName;
+            return this;
+        }
+
+        /**
+         * The Bluetooth Device Address is the address to which the OOB data belongs.
+         *
+         * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets.
+         *
+         * <p> Address is encoded in Little Endian order.
+         *
+         * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00
+         */
+        private final byte[] mDeviceAddressWithType;
+
+        /**
+         * During an LE connection establishment, one must be in the Peripheral mode and the other
+         * in the Central role.
+         *
+         * <p>Possible Values:
+         * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
+         * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
+         * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
+         * Peripheral Preferred
+         * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
+         * 0x04 - 0xFF Reserved
+         */
+        private final @LeRole int mLeDeviceRole;
+
+        /**
+         * Temporary key value from the Security Manager.
+         *
+         * <p> Must be {@link LE_TK_OCTETS} in size
+         */
+        private byte[] mLeTemporaryKey = null;
+
+        /**
+         * Defines the representation of the external appearance of the device.
+         *
+         * <p>For example, a mouse, remote control, or keyboard.
+         *
+         * <p>Used for visual on discovering device to represent icon/string/etc...
+         */
+        private byte[] mLeAppearance = null;
+
+        /**
+         * Contains which discoverable mode to use, BR/EDR support and capability.
+         *
+         * <p>Possible LE Flags:
+         * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
+         * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
+         * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
+         * LMP Feature Mask Definitions.
+         * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
+         * Same Device Capable (Controller).
+         * Bit 49 of LMP Feature Mask Definitions.
+         * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
+         * Same Device Capable (Host).
+         * Bit 55 of LMP Feature Mask Definitions.
+         * <b>0x05- 0x07 Reserved</b>
+         */
+        private @LeFlag int mLeFlags = LE_FLAG_GENERAL_DISCOVERY_MODE; // Invalid default
+
+        /**
+         * Constructing an OobData object for use with LE requires
+         * a LE Device Address and LE Device Role as well as the Confirmation
+         * and optionally, the Randomizer, however it is recommended to use.
+         *
+         * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS}
+         * octets of data. Data is derived from controller/host stack and is required for
+         * pairing OOB.
+         * @param deviceAddressWithType 7 bytes containing the 6 byte address with the 1 byte
+         * address type.
+         * @param leDeviceRole indicating device's role and preferences (Central or Peripheral)
+         *
+         * <p>Possible Values:
+         * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
+         * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
+         * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
+         * Peripheral Preferred
+         * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
+         * 0x04 - 0xFF Reserved
+         *
+         * @throws IllegalArgumentException if deviceAddressWithType is not
+         *                                  {@link LE_DEVICE_ADDRESS_OCTETS} octets
+         * @throws NullPointerException if any argument is null.
+         */
+        private LeBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] deviceAddressWithType,
+                @LeRole int leDeviceRole) {
+            Preconditions.checkNotNull(confirmationHash);
+            Preconditions.checkNotNull(deviceAddressWithType);
+            if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
+                throw new IllegalArgumentException("confirmationHash must be "
+                    + OobData.CONFIRMATION_OCTETS + " octets in length.");
+            }
+            this.mConfirmationHash = confirmationHash;
+            if (deviceAddressWithType.length != OobData.DEVICE_ADDRESS_OCTETS) {
+                throw new IllegalArgumentException("confirmationHash must be "
+                    + OobData.DEVICE_ADDRESS_OCTETS+ " octets in length.");
+            }
+            this.mDeviceAddressWithType = deviceAddressWithType;
+            if (leDeviceRole < LE_DEVICE_ROLE_PERIPHERAL_ONLY
+                    || leDeviceRole > LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL) {
+                throw new IllegalArgumentException("leDeviceRole must be a valid value.");
+            }
+            this.mLeDeviceRole = leDeviceRole;
+        }
+
+        /**
+         * Sets the Temporary Key value to be used by the LE Security Manager during
+         * LE pairing.
+         *
+         * @param leTemporaryKey byte array that shall be 16 bytes. Please see Bluetooth CSSv6,
+         * Part A 1.8 for a detailed description.
+         *
+         * @return {@link OobData#Builder}
+         *
+         * @throws IllegalArgumentException if the leTemporaryKey is an invalid format.
+         * @throws NullinterException if leTemporaryKey is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public LeBuilder setLeTemporaryKey(@NonNull byte[] leTemporaryKey) {
+            Preconditions.checkNotNull(leTemporaryKey);
+            if (leTemporaryKey.length != LE_TK_OCTETS) {
+                throw new IllegalArgumentException("leTemporaryKey must be "
+                        + LE_TK_OCTETS + " octets in length.");
+            }
+            this.mLeTemporaryKey = leTemporaryKey;
+            return this;
+        }
+
+        /**
+         * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
+         * of data. Data is derived from controller/host stack and is required for pairing OOB.
+         * Also, randomizerHash may be all 0s or null in which case it becomes all 0s.
+         *
+         * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed.
+         * @throws NullPointerException if randomizerHash is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public LeBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
+            Preconditions.checkNotNull(randomizerHash);
+            if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
+                throw new IllegalArgumentException("randomizerHash must be "
+                    + OobData.RANDOMIZER_OCTETS + " octets in length.");
+            }
+            this.mRandomizerHash = randomizerHash;
+            return this;
+        }
+
+        /**
+         * Sets the LE Flags necessary for the pairing scenario or discovery mode.
+         *
+         * @param leFlags enum value representing the 1 octet of data about discovery modes.
+         *
+         * <p>Possible LE Flags:
+         * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
+         * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
+         * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
+         * LMP Feature Mask Definitions.
+         * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
+         * Same Device Capable (Controller) Bit 49 of LMP Feature Mask Definitions.
+         * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
+         * Same Device Capable (Host).
+         * Bit 55 of LMP Feature Mask Definitions.
+         * 0x05- 0x07 Reserved
+         *
+         * @throws IllegalArgumentException for invalid flag
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public LeBuilder setLeFlags(@LeFlag int leFlags) {
+            if (leFlags < LE_FLAG_LIMITED_DISCOVERY_MODE || leFlags > LE_FLAG_SIMULTANEOUS_HOST) {
+                throw new IllegalArgumentException("leFlags must be a valid value.");
+            }
+            this.mLeFlags = leFlags;
+            return this;
+        }
+
+        /**
+         * Validates and builds the {@link OobData} object for LE Security.
+         *
+         * @return {@link OobData} with given builder values
+         *
+         * @throws IllegalStateException if either of the 2 required fields were not set.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public OobData build() {
+            final OobData oob =
+                    new OobData(this.mDeviceAddressWithType, this.mLeDeviceRole,
+                            this.mConfirmationHash);
+
+            // If we have values, set them, otherwise use default
+            oob.mLeTemporaryKey =
+                    (this.mLeTemporaryKey != null) ? this.mLeTemporaryKey : oob.mLeTemporaryKey;
+            oob.mLeAppearance = (this.mLeAppearance != null)
+                    ? this.mLeAppearance : oob.mLeAppearance;
+            oob.mLeFlags = (this.mLeFlags != 0xF) ? this.mLeFlags : oob.mLeFlags;
+            oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName;
+            oob.mRandomizerHash = this.mRandomizerHash;
+            return oob;
+        }
     }
 
-    public byte[] getLeSecureConnectionsConfirmation() {
-        return mLeSecureConnectionsConfirmation;
+    /**
+     * Builds an {@link OobData} object and validates that the required combination
+     * of values are present to create the Classic specific OobData type.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class ClassicBuilder {
+        // Used by both Classic and LE
+        /**
+         * It is recommended that this Hash C is generated anew for each
+         * pairing.
+         *
+         * <p>It should be noted that on passive NFC this isn't possible as the data is static
+         * and immutable.
+         *
+         * @hide
+         */
+        private byte[] mConfirmationHash = null;
+
+        /**
+         * Optional, but adds more validity to the pairing.
+         *
+         * <p>If not present a value of 0 is assumed.
+         *
+         * @hide
+         */
+        private byte[] mRandomizerHash = new byte[] {
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        };
+
+        /**
+         * The Bluetooth Device user-friendly name presented over Bluetooth Technology.
+         *
+         * <p>This is the name that may be displayed to the device user as part of the UI.
+         *
+         * @hide
+         */
+        private byte[] mDeviceName = null;
+
+        /**
+         * This length value provides the absolute length of total OOB data block used for
+         * Bluetooth BR/EDR
+         *
+         * <p>OOB communication, which includes the length field itself and the Bluetooth
+         * Device Address.
+         *
+         * <p>The minimum length that may be represented in this field is 8.
+         *
+         * @hide
+         */
+        private final byte[] mClassicLength;
+
+        /**
+         * The Bluetooth Device Address is the address to which the OOB data belongs.
+         *
+         * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets.
+         *
+         * <p> Address is encoded in Little Endian order.
+         *
+         * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00
+         *
+         * @hide
+         */
+        private final byte[] mDeviceAddressWithType;
+
+        /**
+         * Class of Device information is to be used to provide a graphical representation
+         * to the user as part of UI involving operations.
+         *
+         * <p>This is not to be used to determine a particular service can be used.
+         *
+         * <p>The length MUST be {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
+         *
+         * @hide
+         */
+        private byte[] mClassOfDevice = null;
+
+        /**
+         * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS}
+         * octets of data. Data is derived from controller/host stack and is required for pairing
+         * OOB.
+         * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
+         * of data. Data is derived from controller/host stack and is required
+         * for pairing OOB. Also, randomizerHash may be all 0s or null in which case
+         * it becomes all 0s.
+         * @param classicLength byte array representing the length of data from 8-65535 across 2
+         * octets (0xXXXX). Inclusive of this value in the length.
+         * @param deviceAddressWithType byte array representing the Bluetooth Address of the device
+         * that owns the OOB data. (i.e. the originator) [7 octets] this includes the Address Type
+         * as the last octet.
+         *
+         * @throws IllegalArgumentException if any value is not the correct length
+         * @throws NullPointerException if anything passed is null
+         *
+         * @hide
+         */
+        private ClassicBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] classicLength,
+                @NonNull byte[] deviceAddressWithType) {
+            Preconditions.checkNotNull(confirmationHash);
+            Preconditions.checkNotNull(classicLength);
+            Preconditions.checkNotNull(deviceAddressWithType);
+            if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
+                throw new IllegalArgumentException("confirmationHash must be "
+                    + OobData.CONFIRMATION_OCTETS + " octets in length.");
+            }
+            this.mConfirmationHash = confirmationHash;
+            if (classicLength.length != OOB_LENGTH_OCTETS) {
+                throw new IllegalArgumentException("classicLength must be "
+                        + OOB_LENGTH_OCTETS + " octets in length.");
+            }
+            this.mClassicLength = classicLength;
+            if (deviceAddressWithType.length != DEVICE_ADDRESS_OCTETS) {
+                throw new IllegalArgumentException("deviceAddressWithType must be "
+                        + DEVICE_ADDRESS_OCTETS + " octets in length.");
+            }
+            this.mDeviceAddressWithType = deviceAddressWithType;
+        }
+
+        /**
+         * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
+         * of data. Data is derived from controller/host stack and is required for pairing OOB.
+         * Also, randomizerHash may be all 0s or null in which case it becomes all 0s.
+         *
+         * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed.
+         * @throws NullPointerException if randomizerHash is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public ClassicBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
+            Preconditions.checkNotNull(randomizerHash);
+            if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
+                throw new IllegalArgumentException("randomizerHash must be "
+                    + OobData.RANDOMIZER_OCTETS + " octets in length.");
+            }
+            this.mRandomizerHash = randomizerHash;
+            return this;
+        }
+
+        /**
+         * Sets the Bluetooth Device name to be used for UI purposes.
+         *
+         * <p>Optional attribute.
+         *
+         * @param deviceName byte array representing the name, may be 0 in length, not null.
+         *
+         * @return {@link OobData#ClassicBuilder}
+         *
+         * @throws NullPointerException if deviceName is null
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public ClassicBuilder setDeviceName(@NonNull byte[] deviceName) {
+            Preconditions.checkNotNull(deviceName);
+            this.mDeviceName = deviceName;
+            return this;
+        }
+
+        /**
+         * Sets the Bluetooth Class of Device; used for UI purposes only.
+         *
+         * <p>Not an indicator of available services!
+         *
+         * <p>Optional attribute.
+         *
+         * @param classOfDevice byte array of {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
+         *
+         * @return {@link OobData#ClassicBuilder}
+         *
+         * @throws IllegalArgumentException if length is not equal to
+         * {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
+         * @throws NullPointerException if classOfDevice is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public ClassicBuilder setClassOfDevice(@NonNull byte[] classOfDevice) {
+            Preconditions.checkNotNull(classOfDevice);
+            if (classOfDevice.length != OobData.CLASS_OF_DEVICE_OCTETS) {
+                throw new IllegalArgumentException("classOfDevice must be "
+                        + OobData.CLASS_OF_DEVICE_OCTETS + " octets in length.");
+            }
+            this.mClassOfDevice = classOfDevice;
+            return this;
+        }
+
+        /**
+         * Validates and builds the {@link OobDat object for Classic Security.
+         *
+         * @return {@link OobData} with previously given builder values.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public OobData build() {
+            final OobData oob =
+                    new OobData(this.mClassicLength, this.mDeviceAddressWithType,
+                            this.mConfirmationHash);
+            // If we have values, set them, otherwise use default
+            oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName;
+            oob.mClassOfDevice = (this.mClassOfDevice != null)
+                    ? this.mClassOfDevice : oob.mClassOfDevice;
+            oob.mRandomizerHash = this.mRandomizerHash;
+            return oob;
+        }
     }
 
-    public void setLeSecureConnectionsConfirmation(byte[] leSecureConnectionsConfirmation) {
-        mLeSecureConnectionsConfirmation = leSecureConnectionsConfirmation;
+    // Members (Defaults for Optionals must be set or Parceling fails on NPE)
+    // Both
+    private final byte[] mDeviceAddressWithType;
+    private final byte[] mConfirmationHash;
+    private byte[] mRandomizerHash = new byte[] {
+        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+    };
+    // Default the name to "Bluetooth Device"
+    private byte[] mDeviceName = new byte[] {
+        // Bluetooth
+        0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68,
+        // <space>Device
+        0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65
+    };
+
+    // Classic
+    private final byte[] mClassicLength;
+    private byte[] mClassOfDevice = new byte[CLASS_OF_DEVICE_OCTETS];
+
+    // LE
+    private final @LeRole int mLeDeviceRole;
+    private byte[] mLeTemporaryKey = new byte[LE_TK_OCTETS];
+    private byte[] mLeAppearance = new byte[LE_APPEARANCE_OCTETS];
+    private @LeFlag int mLeFlags = LE_FLAG_LIMITED_DISCOVERY_MODE;
+
+    /**
+     * @return byte array representing the MAC address of a bluetooth device.
+     * The Address is 6 octets long with a 1 octet address type associated with the address.
+     *
+     * <p>For classic this will be 6 byte address plus the default of PUBLIC_ADDRESS Address Type.
+     * For LE there are more choices for Address Type.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public byte[] getDeviceAddressWithType() {
+        return mDeviceAddressWithType;
     }
 
-    public byte[] getLeSecureConnectionsRandom() {
-        return mLeSecureConnectionsRandom;
+    /**
+     * @return byte array representing the confirmationHash value
+     * which is used to confirm the identity to the controller.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public byte[] getConfirmationHash() {
+        return mConfirmationHash;
     }
 
-    public void setLeSecureConnectionsRandom(byte[] leSecureConnectionsRandom) {
-        mLeSecureConnectionsRandom = leSecureConnectionsRandom;
+    /**
+     * @return byte array representing the randomizerHash value
+     * which is used to verify the identity of the controller.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public byte[] getRandomizerHash() {
+        return mRandomizerHash;
     }
 
-    public OobData() {
+    /**
+     * @return Device Name used for displaying name in UI.
+     *
+     * <p>Also, this will be populated with the LE Local Name if the data is for LE.
+     *
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public byte[] getDeviceName() {
+        return mDeviceName;
+    }
+
+    /**
+     * @return byte array representing the oob data length which is the length
+     * of all of the data including these octets.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public byte[] getClassicLength() {
+        return mClassicLength;
+    }
+
+    /**
+     * @return byte array representing the class of device for UI display.
+     *
+     * <p>Does not indicate services available; for display only.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public byte[] getClassOfDevice() {
+        return mClassOfDevice;
+    }
+
+    /**
+     * @return Temporary Key used for LE pairing.
+     *
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public byte[] getLeTemporaryKey() {
+        return mLeTemporaryKey;
+    }
+
+    /**
+     * @return Appearance used for LE pairing. For use in UI situations
+     * when determining what sort of icons or text to display regarding
+     * the device.
+     *
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public byte[] getLeAppearance() {
+        return mLeTemporaryKey;
+    }
+
+    /**
+     * @return Flags used to determing discoverable mode to use, BR/EDR Support, and Capability.
+     *
+     * <p>Possible LE Flags:
+     * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
+     * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
+     * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
+     * LMP Feature Mask Definitions.
+     * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
+     * Same Device Capable (Controller).
+     * Bit 49 of LMP Feature Mask Definitions.
+     * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
+     * Same Device Capable (Host).
+     * Bit 55 of LMP Feature Mask Definitions.
+     * <b>0x05- 0x07 Reserved</b>
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    @LeFlag
+    public int getLeFlags() {
+        return mLeFlags;
+    }
+
+    /**
+     * @return the supported and preferred roles of the LE device.
+     *
+     * <p>Possible Values:
+     * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
+     * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
+     * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
+     * Peripheral Preferred
+     * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
+     * 0x04 - 0xFF Reserved
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    @LeRole
+    public int getLeDeviceRole() {
+        return mLeDeviceRole;
+    }
+
+    /**
+     * Classic Security Constructor
+     */
+    private OobData(@NonNull byte[] classicLength, @NonNull byte[] deviceAddressWithType,
+            @NonNull byte[] confirmationHash) {
+        mClassicLength = classicLength;
+        mDeviceAddressWithType = deviceAddressWithType;
+        mConfirmationHash = confirmationHash;
+        mLeDeviceRole = -1; // Satisfy final
+    }
+
+    /**
+     * LE Security Constructor
+     */
+    private OobData(@NonNull byte[] deviceAddressWithType, @LeRole int leDeviceRole,
+            @NonNull byte[] confirmationHash) {
+        mDeviceAddressWithType = deviceAddressWithType;
+        mLeDeviceRole = leDeviceRole;
+        mConfirmationHash = confirmationHash;
+        mClassicLength = new byte[OOB_LENGTH_OCTETS]; // Satisfy final
     }
 
     private OobData(Parcel in) {
-        mLeBluetoothDeviceAddress = in.createByteArray();
-        mSecurityManagerTk = in.createByteArray();
-        mLeSecureConnectionsConfirmation = in.createByteArray();
-        mLeSecureConnectionsRandom = in.createByteArray();
+        // Both
+        mDeviceAddressWithType = in.createByteArray();
+        mConfirmationHash = in.createByteArray();
+        mRandomizerHash = in.createByteArray();
+        mDeviceName = in.createByteArray();
+
+        // Classic
+        mClassicLength = in.createByteArray();
+        mClassOfDevice = in.createByteArray();
+
+        // LE
+        mLeDeviceRole = in.readInt();
+        mLeTemporaryKey = in.createByteArray();
+        mLeAppearance = in.createByteArray();
+        mLeFlags = in.readInt();
     }
 
+    /**
+     * @hide
+     */
     @Override
     public int describeContents() {
         return 0;
     }
 
+    /**
+     * @hide
+     */
     @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeByteArray(mLeBluetoothDeviceAddress);
-        out.writeByteArray(mSecurityManagerTk);
-        out.writeByteArray(mLeSecureConnectionsConfirmation);
-        out.writeByteArray(mLeSecureConnectionsRandom);
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        // Both
+        // Required
+        out.writeByteArray(mDeviceAddressWithType);
+        // Required
+        out.writeByteArray(mConfirmationHash);
+        // Optional
+        out.writeByteArray(mRandomizerHash);
+        // Optional
+        out.writeByteArray(mDeviceName);
+
+        // Classic
+        // Required
+        out.writeByteArray(mClassicLength);
+        // Optional
+        out.writeByteArray(mClassOfDevice);
+
+        // LE
+        // Required
+        out.writeInt(mLeDeviceRole);
+        // Required
+        out.writeByteArray(mLeTemporaryKey);
+        // Optional
+        out.writeByteArray(mLeAppearance);
+        // Optional
+        out.writeInt(mLeFlags);
     }
 
+    // For Parcelable
     public static final @android.annotation.NonNull Parcelable.Creator<OobData> CREATOR =
             new Parcelable.Creator<OobData>() {
         public OobData createFromParcel(Parcel in) {
@@ -108,4 +969,47 @@
             return new OobData[size];
         }
     };
+
+    /**
+     * @return a {@link String} representation of the OobData object.
+     *
+     * @hide
+     */
+    @Override
+    @NonNull
+    public String toString() {
+        return "OobData: \n\t"
+            // Both
+            + "Device Address With Type: " +  toHexString(mDeviceAddressWithType) + "\n\t"
+            + "Confirmation: " + toHexString(mConfirmationHash) + "\n\t"
+            + "Randomizer: " + toHexString(mRandomizerHash) + "\n\t"
+            + "Device Name: " + toHexString(mDeviceName) + "\n\t"
+            // Classic
+            + "OobData Length: " +  toHexString(mClassicLength) + "\n\t"
+            + "Class of Device: " +  toHexString(mClassOfDevice) + "\n\t"
+            // LE
+            + "LE Device Role: " + toHexString(mLeDeviceRole) + "\n\t"
+            + "LE Temporary Key: " + toHexString(mLeTemporaryKey) + "\n\t"
+            + "LE Appearance: " + toHexString(mLeAppearance) + "\n\t"
+            + "LE Flags: " + toHexString(mLeFlags) + "\n\t";
+    }
+
+    @NonNull
+    private String toHexString(@NonNull int b) {
+        return toHexString(new byte[] {(byte) b});
+    }
+
+    @NonNull
+    private String toHexString(@NonNull byte b) {
+        return toHexString(new byte[] {b});
+    }
+
+    @NonNull
+    private String toHexString(@NonNull byte[] array) {
+        StringBuilder builder = new StringBuilder(array.length * 2);
+        for (byte b: array) {
+            builder.append(String.format("%02x", b));
+        }
+        return builder.toString();
+    }
 }
