Address all comments.

Change-Id: I765d91f394c4c57c8906761c47d0136b3acd0a3c
diff --git a/android-lib/src/main/java/io/v/android/libs/discovery/ble/BlePlugin.java b/android-lib/src/main/java/io/v/android/libs/discovery/ble/BlePlugin.java
index 88a2fbf..ddff860 100644
--- a/android-lib/src/main/java/io/v/android/libs/discovery/ble/BlePlugin.java
+++ b/android-lib/src/main/java/io/v/android/libs/discovery/ble/BlePlugin.java
@@ -27,6 +27,8 @@
 
 import org.joda.time.Duration;
 
+import com.google.common.util.concurrent.Uninterruptibles;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
@@ -48,7 +50,7 @@
 import io.v.x.ref.lib.discovery.Advertisement;
 
 /**
- * BlePlugin implements the Discovery Plugin Interface for Bluetooth.
+ * The Discovery Plugin Interface for Bluetooth.
  */
 public class BlePlugin {
     // We are using a constant for the MTU because Android and paypal/gatt don't get along
@@ -91,43 +93,35 @@
     // A thread to wait for the cancellation of a particular advertisement.  VContext.done().await()
     // is blocking so have to spin up a thread per outstanding advertisement.
     private class AdvertisementCancellationRunner implements Runnable{
-        private VContext mCtx;
+        private VContext ctx;
 
-        private int mId;
+        private int id;
         AdvertisementCancellationRunner(VContext ctx, int id) {
-            mId = id;
-            mCtx = ctx;
+            this.id = id;
+            this.ctx = ctx;
         }
 
         @Override
         public void run() {
-            try {
-                mCtx.done().await();
-            } catch (InterruptedException e) {
-                // Ignore interruptions.
-            }
-            BlePlugin.this.removeAdvertisement(mId);
+            Uninterruptibles.awaitUninterruptibly(ctx.done());
+            BlePlugin.this.removeAdvertisement(id);
         }
     }
 
     // Similar to AdvertisementCancellationRunner except for scanning.
     private class ScannerCancellationRunner implements Runnable{
-        private VContext mCtx;
+        private VContext ctx;
 
-        private int mId;
+        private int id;
         ScannerCancellationRunner(VContext ctx, int id) {
-            mId = id;
-            mCtx = ctx;
+            this.id = id;
+            this.ctx = ctx;
         }
 
         @Override
         public void run() {
-            try {
-                mCtx.done().await();
-            } catch (InterruptedException e) {
-                // Ignore interruptions.
-            }
-            BlePlugin.this.removeScanner(mId);
+            Uninterruptibles.awaitUninterruptibly(ctx.done());
+            BlePlugin.this.removeScanner(id);
         }
     }
 
@@ -138,7 +132,8 @@
         advCancellationThreads = new HashMap<>();
 
         scannerLock = new Object();
-        cachedDevices = new DeviceCache(new Duration(5 * 60000));
+        cachedDevices = new DeviceCache(Duration.standardMinutes(5));
+        ;
         scanCancellationThreads = new HashMap<>();
         isScanning = false;
         pendingCalls = new HashSet<>();
@@ -148,18 +143,21 @@
         this.androidContext = androidContext;
         BluetoothManager manager = (BluetoothManager) androidContext.getSystemService(
                 Context.BLUETOOTH_SERVICE);
-        bluetoothGattServer = manager.openGattServer(androidContext, new BluetoothGattServerCallback() {
+        bluetoothGattServer = manager.openGattServer(androidContext,
+                new BluetoothGattServerCallback() {
             @Override
             public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
                 super.onConnectionStateChange(device, status, newState);
             }
 
             @Override
-            public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
+            public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,
+                                                    int offset,
+                                                    BluetoothGattCharacteristic characteristic) {
                 super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
                 byte[] total =characteristic.getValue();
                 byte[] res = {};
-                // Only send MTU - 1 bytes. The first byte of all packets is the op code..
+                // Only send MTU - 1 bytes. The first byte of all packets is the op code.
                 if (offset < total.length) {
                     int finalByte = offset + MTU - 1;
                     if (finalByte > total.length) {
@@ -177,9 +175,9 @@
 
     // Converts a Vanadium Advertisement to a Bluetooth gatt service.
     private BluetoothGattService convertToService(Advertisement adv) throws IOException {
-        Map<UUID, byte[]> attributes = BleAdvertisementConverter.vadvertismentToBleAttr(adv);
+        Map<UUID, byte[]> attributes = BleAdvertisementConverter.vAdvertismentToBleAttr(adv);
         BluetoothGattService service = new BluetoothGattService(
-                UUIDUtil.UuidtUUID(adv.getServiceUuid()), BluetoothGattService.SERVICE_TYPE_PRIMARY);
+                UUIDUtil.UuidToUUID(adv.getServiceUuid()), BluetoothGattService.SERVICE_TYPE_PRIMARY);
         for (Map.Entry<UUID, byte[]> entry : attributes.entrySet()) {
             BluetoothGattCharacteristic ch = new BluetoothGattCharacteristic(entry.getKey(), 0,
                     BluetoothGattCharacteristic.PERMISSION_READ);
@@ -255,8 +253,10 @@
                 @Override
                 public void onScanResult(int callbackType, ScanResult result) {
                     // in L the only value for callbackType is CALLBACK_TYPE_ALL_MATCHES, so
-                    // we don't look at it's value.
+                    // we don't look at its value.
                     ScanRecord record = result.getScanRecord();
+                    // Use 1001 to denote that this is a Vanadium device.  We picked an id that is
+                    // currently not in use.
                     byte[] data = record.getManufacturerSpecificData(1001);
                     ByteBuffer buffer = ByteBuffer.wrap(data);
                     final long hash = buffer.getLong();
@@ -282,7 +282,7 @@
                                                     bleAttrToVAdvertisement(entry.getValue());
                                     advs.add(adv);
                                 } catch (IOException e) {
-                                    Log.e("vanadium","Failed to convert advertisemetn" + e);
+                                    Log.e("vanadium","Failed to convert advertisement" + e);
                                 }
                             }
                             cachedDevices.saveDevice(hash, advs, deviceId);
diff --git a/android-lib/src/main/java/io/v/android/libs/discovery/ble/BluetoothGattClientCallback.java b/android-lib/src/main/java/io/v/android/libs/discovery/ble/BluetoothGattClientCallback.java
index 067ba8d..62e3c3e 100644
--- a/android-lib/src/main/java/io/v/android/libs/discovery/ble/BluetoothGattClientCallback.java
+++ b/android-lib/src/main/java/io/v/android/libs/discovery/ble/BluetoothGattClientCallback.java
@@ -18,9 +18,11 @@
 import java.util.UUID;
 
 /**
- * BluetoothGattClientCallback is a handler for responses from a GattServer.
+ * A handler for responses from a GattServer.
  */
 public class BluetoothGattClientCallback extends BluetoothGattCallback {
+    // We want to ignore the GATT and GAP services, which are 1800 and 1801 respectively.
+    static final String GATT_AND_GAP_PREFIX = "0000180";
     public interface Callback {
         void handle(Map<UUID, Map<UUID, byte[]>> services);
     }
@@ -43,7 +45,7 @@
     public void onServicesDiscovered(BluetoothGatt gatt, int status) {
         for (BluetoothGattService service : gatt.getServices()) {
             // Skip the GATT AND GAP Services.
-            if (service.getUuid().toString().startsWith("0000180")) {
+            if (service.getUuid().toString().startsWith(GATT_AND_GAP_PREFIX)) {
                 continue;
             }
             services.put(service.getUuid(), new HashMap<UUID, byte[]>());
diff --git a/lib/src/main/java/io/v/impl/google/lib/discovery/DeviceCache.java b/lib/src/main/java/io/v/impl/google/lib/discovery/DeviceCache.java
index 480de84..14ecf28 100644
--- a/lib/src/main/java/io/v/impl/google/lib/discovery/DeviceCache.java
+++ b/lib/src/main/java/io/v/impl/google/lib/discovery/DeviceCache.java
@@ -5,6 +5,8 @@
 package io.v.impl.google.lib.discovery;
 
 
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.SetMultimap;
 import com.google.common.collect.Sets;
 
 import org.joda.time.Duration;
@@ -15,13 +17,148 @@
 import java.util.Set;
 import java.util.HashSet;
 import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import io.v.x.ref.lib.discovery.Advertisement;
 
+/**
+ * A Cache of ble devices that were seen recently.  The current Vanadium BLE protocol requires
+ * connecting to the advertiser to grab the attributes and the addrs.  This can be expensive
+ * so we only refetch the data if it hash changed.
+ */
 public class DeviceCache {
     private Map<Long, CacheEntry> cachedDevices;
     private Map<String, CacheEntry> knownIds;
 
+
+    final AtomicInteger nextScanner = new AtomicInteger(0);
+    private SetMultimap<UUID, Advertisement> knownServices;
+    private Map<Integer, VScanner> scannersById;
+    private SetMultimap<UUID, VScanner> scannersByUUID;
+
+    private Duration maxAge;
+
+
+    public DeviceCache(Duration maxAge) {
+        cachedDevices = new HashMap<>();
+        knownIds = new HashMap<>();
+        knownServices = HashMultimap.create();
+        scannersById = new HashMap<>();
+        scannersByUUID = HashMultimap.create();
+        this.maxAge = maxAge;
+    }
+
+    /**
+     * Returns whether this hash has been seen before.
+     *
+     * @param hash the hash of the advertisement
+     * @param deviceId the deviceId of the advertisement (used to handle rotating ids).
+     * @return true iff this hash is in the cache.
+     */
+    public boolean haveSeenHash(long hash, String deviceId) {
+        synchronized (this) {
+            CacheEntry entry = cachedDevices.get(hash);
+            if (entry != null) {
+                entry.lastSeen = new Date();
+                if (!entry.deviceId.equals(deviceId)) {
+                    // This probably happened becuase a device has changed it's ble mac address.
+                    // We need to update the mac address for this entry.
+                    knownIds.remove(entry.deviceId);
+                    entry.deviceId = deviceId;
+                    knownIds.put(deviceId, entry);
+                }
+            }
+            return entry != null;
+        }
+    }
+
+    /**
+     * Saves the set of advertisements for this deviceId and hash
+     *
+     * @param hash the hash provided by the advertisement.
+     * @param advs the advertisements exposed by the device.
+     * @param deviceId the id of the device.
+     */
+    public void saveDevice(long hash, Set<Advertisement> advs, String deviceId) {
+        CacheEntry entry = new CacheEntry(advs, hash, deviceId);
+        synchronized (this) {
+            CacheEntry oldEntry = knownIds.get(deviceId);
+            Set<Advertisement> oldValues = null;
+            if (oldEntry != null) {
+                cachedDevices.remove(oldEntry.hash);
+                knownIds.remove(oldEntry.deviceId);
+                oldValues = oldEntry.advertisements;
+            } else {
+                oldValues = new HashSet<>();
+            }
+            Set<Advertisement> removed = Sets.difference(oldValues, advs);
+            for (Advertisement adv : removed) {
+                UUID uuid = UUIDUtil.UuidToUUID(adv.getServiceUuid());
+                adv.setLost(true);
+                knownServices.remove(uuid, adv);
+                handleUpdate(adv);
+            }
+
+            Set<Advertisement> added = Sets.difference(advs, oldValues);
+            for (Advertisement adv: added) {
+                UUID uuid = UUIDUtil.UuidToUUID(adv.getServiceUuid());
+                knownServices.put(uuid, adv);
+                handleUpdate(adv);
+            }
+            cachedDevices.put(hash, entry);
+            CacheEntry oldDeviceEntry = knownIds.get(deviceId);
+            if (oldDeviceEntry != null) {
+                // Delete the old hash value.
+                cachedDevices.remove(hash);
+            }
+            knownIds.put(deviceId, entry);
+        }
+    }
+
+    private void handleUpdate(Advertisement adv) {
+        UUID uuid = UUIDUtil.UuidToUUID(adv.getServiceUuid());
+        Set<VScanner> scanners = scannersByUUID.get(uuid);
+        if (scanners == null) {
+            return;
+        }
+        for (VScanner scanner : scanners) {
+            scanner.getHandler().handleUpdate(adv);
+        }
+    }
+
+    /**
+     * Adds a scanner that will be notified when advertisements that match its query have changed.
+     *
+     * @return the handle of the scanner that can be used to remove the scanner.
+     */
+    public int addScanner(VScanner scanner) {
+        synchronized (this) {
+            int id = nextScanner.addAndGet(1);
+            scannersById.put(id, scanner);
+            scannersByUUID.put(scanner.getmServiceUUID(), scanner);
+            Set<Advertisement> knownAdvs = knownServices.get(scanner.getmServiceUUID());
+            if (knownAdvs != null) {
+                for (Advertisement adv : knownAdvs) {
+                    scanner.getHandler().handleUpdate(adv);
+                }
+            }
+            return id;
+        }
+    }
+
+    /**
+     * Removes the scanner matching this id.  This scanner will stop getting updates.
+     */
+    public void removeScanner(int id) {
+        synchronized (this) {
+            VScanner scanner = scannersById.get(id);
+            if (scanner != null) {
+                scannersByUUID.remove(scanner.getmServiceUUID(), scanner);
+                scannersById.remove(id);
+            }
+        }
+    }
+
     private class CacheEntry {
         Set<Advertisement> advertisements;
 
@@ -39,134 +176,4 @@
         }
     }
 
-    int nextScanner;
-    private Map<UUID, Set<Advertisement>> knownServices;
-    private Map<Integer, VScanner> scannersById;
-    private Map<UUID, Set<VScanner>> scannersByUUID;
-
-    private Duration maxAge;
-
-
-    public DeviceCache(Duration maxAge) {
-        cachedDevices = new HashMap<>();
-        knownIds = new HashMap<>();
-        knownServices = new HashMap<>();
-        scannersById = new HashMap<>();
-        scannersByUUID = new HashMap<>();
-        this.maxAge = maxAge;
-        nextScanner = 0;
-    }
-
-    public boolean haveSeenHash(long hash, String deviceId) {
-        synchronized (this) {
-            CacheEntry entry = cachedDevices.get(hash);
-            if (entry != null) {
-                entry.lastSeen = new Date();
-                if (!entry.deviceId.equals(deviceId)) {
-                    // This probably happened becuase a device has changed it's ble mac address.
-                    // We need to update the mac address for this entry.
-                    knownIds.remove(entry.deviceId);
-                    entry.deviceId = deviceId;
-                    knownIds.put(deviceId, entry);
-                }
-            }
-            return entry != null;
-        }
-    }
-
-    public void saveDevice(long hash, Set<Advertisement> advs, String deviceId) {
-        CacheEntry entry = new CacheEntry(advs, hash, deviceId);
-        synchronized (this) {
-            CacheEntry oldEntry = knownIds.get(deviceId);
-            Set<Advertisement> oldValues = null;
-            if (oldEntry != null) {
-                cachedDevices.remove(oldEntry.hash);
-                knownIds.remove(oldEntry.deviceId);
-                oldValues = oldEntry.advertisements;
-            } else {
-                oldValues = new HashSet<>();
-            }
-            Sets.SetView<Advertisement> removed = Sets.difference(oldValues, advs);
-            for (Advertisement adv : removed) {
-                UUID uuid = UUIDUtil.UuidtUUID(adv.getServiceUuid());
-                Set<Advertisement> set = knownServices.get(uuid);
-
-                if (set != null) {
-                    set.remove(adv);
-                    adv.setLost(true);
-                    handleUpdate(adv);
-
-                    if (set.size() == 0) {
-                        knownServices.remove(uuid);
-                    }
-                }
-            }
-
-            Sets.SetView<Advertisement> added = Sets.difference(advs, oldValues);
-            for (Advertisement adv: added) {
-                UUID uuid = UUIDUtil.UuidtUUID(adv.getServiceUuid());
-                Set<Advertisement> set = knownServices.get(uuid);
-                if (set == null) {
-                    set = new HashSet<>();
-                    knownServices.put(uuid, set);
-                }
-                set.add(adv);
-                handleUpdate(adv);
-            }
-            cachedDevices.put(hash, entry);
-            CacheEntry oldDeviceEntry = knownIds.get(deviceId);
-            if (oldDeviceEntry != null) {
-                // Delete the old hash value.
-                cachedDevices.remove(hash);
-            }
-            knownIds.put(deviceId, entry);
-        }
-    }
-
-    private void handleUpdate(Advertisement adv) {
-        UUID uuid = UUIDUtil.UuidtUUID(adv.getServiceUuid());
-        Set<VScanner> scanners = scannersByUUID.get(uuid);
-        if (scanners == null) {
-            return;
-        }
-        for (VScanner scanner : scanners) {
-            scanner.getHandler().handleUpdate(adv);
-        }
-    }
-
-    public int addScanner(VScanner scanner) {
-        synchronized (this) {
-            int id = nextScanner++;
-            scannersById.put(id, scanner);
-            Set<VScanner> scanners = scannersByUUID.get(scanner.getmServiceUUID());
-            if (scanners == null) {
-                scanners = new HashSet<>();
-                scannersByUUID.put(scanner.getmServiceUUID(), scanners);
-            }
-            Set<Advertisement> knownAdvs = knownServices.get(scanner.getmServiceUUID());
-            if (knownAdvs != null) {
-                for (Advertisement adv : knownAdvs) {
-                    scanner.getHandler().handleUpdate(adv);
-                }
-            }
-            scanners.add(scanner);
-            return id;
-        }
-    }
-
-    public void removeScanner(int id) {
-        synchronized (this) {
-            VScanner scanner = scannersById.get(id);
-            if (scanner != null) {
-                Set<VScanner> list = scannersByUUID.get(scanner.getmServiceUUID());
-                if (list != null) {
-                    list.remove(scanner);
-                    if (list.size() == 0) {
-                        scannersByUUID.remove(scanner.getmServiceUUID());
-                    }
-                }
-                scannersById.remove(id);
-            }
-        }
-    }
 }
diff --git a/lib/src/main/java/io/v/impl/google/lib/discovery/EncodingUtil.java b/lib/src/main/java/io/v/impl/google/lib/discovery/EncodingUtil.java
index 76c8775..0441eb6 100644
--- a/lib/src/main/java/io/v/impl/google/lib/discovery/EncodingUtil.java
+++ b/lib/src/main/java/io/v/impl/google/lib/discovery/EncodingUtil.java
@@ -10,101 +10,115 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
 
+import io.v.v23.vom.BinaryUtil;
 import io.v.x.ref.lib.discovery.EncryptionKey;
 
+/**
+ * A utility to encode and decode fields in io.v.v23.Service fields for use in discovery.
+ */
 public class EncodingUtil {
-    static final Charset utf8 = Charset.forName("UTF-8");
-    private static void writeUint(OutputStream out, int value) throws IOException {
-        if ((value & 0x7f) == value) {
-            out.write((byte) value);
-            return;
-        }
-        int len = 0;
-        while (((value >>> (len * 8)) | 0xff) != 0xff) {
-            len++;
-        }
-        len++;
-        out.write(-len);
-        while (len > 0) {
-            len--;
-            out.write((byte) (value >>> (len * 8)));
-        }
-    }
+    static final Charset UTF8_CHARSET = Charset.forName("UTF-8");
 
-    private static long readUint(InputStream in) throws IOException {
-        int firstByte = in.read();
-        if (firstByte == -1) {
-            // EOF.
-            throw new IOException("Unexpected end of stream");
-        }
-        if ((firstByte & 0x7f) == firstByte) {
-            return firstByte;
-        }
-        int len = -(byte) firstByte;
-        if (len > 8) {
-            throw new IOException("Invalid long byte length");
-        }
-        long value = 0;
-        while (len > 0) {
-            len--;
-            int nextByte = in.read();
-            if (nextByte == -1) {
-                throw new IOException("Unexpected end of stream");
-            }
-            value = (value << 8) | nextByte;
-        }
-        return value;
-    }
-
+    /**
+     * Encodes the addresses passed in.
+     * @param addrs The list of addresses to encode.
+     * @return The byte representation of the encoded addresses.
+     * @throws IOException
+     */
     public static byte[] packAddresses(List<String> addrs) throws IOException {
         ByteArrayOutputStream stream = new ByteArrayOutputStream();
         for (String addr : addrs) {
-            writeUint(stream, addr.length());
-            stream.write(addr.getBytes(utf8));
+            BinaryUtil.encodeUint(stream, addr.length());
+            stream.write(addr.getBytes(UTF8_CHARSET));
         }
         return stream.toByteArray();
     }
 
+    /**
+     * Decodes addresses from a byte array that was encoded by packAddresses
+     * @param input The byte array toe decode
+     * @return The list of addresses.
+     * @throws IOException
+     */
     public static List<String> unpackAddresses(byte[] input) throws IOException {
         ByteArrayInputStream stream = new ByteArrayInputStream(input);
         List<String> output = new ArrayList<>();
         while (stream.available() > 0) {
-            int stringSize = (int)readUint(stream);
+            int stringSize = (int)BinaryUtil.decodeUint(stream);
             byte[] data = new byte[stringSize];
             int read = stream.read(data);
             if (read != stringSize) {
                 throw new IOException("Unexpected end of stream while reading address");
             }
-            output.add(new String(data, utf8));
+            output.add(new String(data, UTF8_CHARSET));
         }
         return output;
     }
 
+    /**
+     * Encode the encryption keys and algorithm passed in.
+     * @param encryptionAlgorithm The encryption algorithm to use.
+     *                            See io.v.x.ref.lib.discovery.Constants for valid values.
+     * @param keys The keys to encode
+     * @return The byte array that is the encoded form.
+     * @throws IOException
+     */
     public static byte[] packEncryptionKeys(int encryptionAlgorithm, List<EncryptionKey> keys)
             throws IOException {
         ByteArrayOutputStream stream = new ByteArrayOutputStream();
-        writeUint(stream, encryptionAlgorithm);
+        BinaryUtil.encodeUint(stream, encryptionAlgorithm);
         for (EncryptionKey key : keys) {
             byte[] byteKey = Bytes.toArray(key);
-            writeUint(stream, byteKey.length);
+            BinaryUtil.encodeUint(stream, byteKey.length);
             stream.write(byteKey);
         }
         return stream.toByteArray();
     }
 
-    static public class KeysAndAlgorithm {
+
+    /**
+     * Decodes the encryption algorithm and keys that was encoded by packEncryptionKeys.
+     * @param input The byte array containg the keys.
+     * @return The keys and the encryption algorithm in input.
+     * @throws IOException
+     */
+    public static KeysAndAlgorithm unpackEncryptionKeys(byte[] input) throws IOException {
+        ByteArrayInputStream stream = new ByteArrayInputStream(input);
+        int algo = (int) BinaryUtil.decodeUint(stream);
+        List<EncryptionKey> keys = new ArrayList<>();
+        while (stream.available() > 0) {
+            int size = (int) BinaryUtil.decodeUint(stream);
+            byte[] key = new byte[size];
+            int read = stream.read(key);
+            if (read != size) {
+                throw new IOException("Unexpected end of file reading keys");
+            }
+            keys.add(new EncryptionKey(Bytes.asList(key)));
+        }
+        return new KeysAndAlgorithm(algo, keys);
+    }
+
+    /**
+     * An object with EncryptionKeys and the encryption algorithm.
+     */
+    public static class KeysAndAlgorithm {
         int encryptionAlgorithm;
         List<EncryptionKey> keys;
+
+        /**
+         * Gets the stored encryption algorithm.
+         */
         public int getEncryptionAlgorithm() {
             return encryptionAlgorithm;
         }
 
+        /**
+         * Gets the stored keys.
+         */
         public List<EncryptionKey> getKeys() {
             return keys;
         }
@@ -115,19 +129,4 @@
         }
     }
 
-    public static KeysAndAlgorithm unpackEncryptionKeys(byte[] input) throws IOException {
-        ByteArrayInputStream stream = new ByteArrayInputStream(input);
-        int algo = (int) readUint(stream);
-        List<EncryptionKey> keys = new ArrayList<>();
-        while (stream.available() > 0) {
-            int size = (int) readUint(stream);
-            byte[] key = new byte[size];
-            int read = stream.read(key);
-            if (read != size) {
-                throw new IOException("Unexpected end of file reading keys");
-            }
-            keys.add(new EncryptionKey(Bytes.asList(key)));
-        }
-        return new KeysAndAlgorithm(algo, keys);
-    }
 }
diff --git a/lib/src/main/java/io/v/impl/google/lib/discovery/ScanHandler.java b/lib/src/main/java/io/v/impl/google/lib/discovery/ScanHandler.java
index fce8119..20414b7 100644
--- a/lib/src/main/java/io/v/impl/google/lib/discovery/ScanHandler.java
+++ b/lib/src/main/java/io/v/impl/google/lib/discovery/ScanHandler.java
@@ -7,13 +7,12 @@
 import io.v.x.ref.lib.discovery.Advertisement;
 
 /**
- * Created by bjornick on 10/5/15.
+ * An interface that is passed into a Vanadium Discovery Scan operation that will handle updates.
  */
 public interface ScanHandler {
     /**
-     * handleUpdate will be called when there is a new advertisement or an update
+     * Called when there is a new advertisement or an update
      * to and old advertisement
-     * @param advertisement The updated advertisement.
      */
     void handleUpdate(Advertisement advertisement);
 }
diff --git a/lib/src/main/java/io/v/impl/google/lib/discovery/UUIDUtil.java b/lib/src/main/java/io/v/impl/google/lib/discovery/UUIDUtil.java
index f754241..9413ce9 100644
--- a/lib/src/main/java/io/v/impl/google/lib/discovery/UUIDUtil.java
+++ b/lib/src/main/java/io/v/impl/google/lib/discovery/UUIDUtil.java
@@ -12,8 +12,11 @@
 import io.v.x.ref.lib.discovery.Uuid;
 
 /**
- * UUIDUtil is a class for generating v5 UUIDs and converting from java.util.UUID and
- * io.v.impl.google.lib.discovery.Uuid.
+ * A class for generating v5 UUIDs and converting from {@link java.util.UUID} and
+ * {@link io.v.x.ref.lib.discovery.Uuid}.  T{@link java.util.UUID} does not provide
+ * any mechanism to compute v5 UUIDs which are used to convert InterfaceNames to service
+ * UUIDs.  Conversion from {@link Uuid} and {@link UUID} is necessary because the VDL type
+ * and the native type are annoying to convert to.
  */
 public class UUIDUtil {
     public static native UUID UUIDForInterfaceName(String name);
@@ -21,11 +24,9 @@
     public static native UUID UUIDForAttributeKey(String key);
 
     /**
-     * Converts from java.util.UUID to io.v.impl.google.lib.discovery.Uuid.
-     * @param id The java.util.UUID
-     * @return The io.v.impl.google.lib.discovery.Uuid version of id
+     * Converts from {@link java.util.UUID} to {@link Uuid}.
      */
-    public static Uuid UUIDtUuid(UUID id) {
+    public static Uuid UUIDToUuid(UUID id) {
         ByteBuffer b = ByteBuffer.allocate(16);
         b.putLong(id.getMostSignificantBits());
         b.putLong(id.getLeastSignificantBits());
@@ -33,11 +34,9 @@
     }
 
     /**
-     * Converts from io.v.impl.google.lib.discovery.Uuid to java.util.UUID
-     * @param id The io.v.impl.google.lib.discovery.Uuid
-     * @return The java.util.UUID version of id
+     * Converts from {@link Uuid} to {@link UUID}
      */
-    public static UUID UuidtUUID(Uuid id) {
+    public static UUID UuidToUUID(Uuid id) {
         ByteBuffer b = ByteBuffer.wrap(Bytes.toArray(id));
         return new UUID(b.getLong(), b.getLong());
     }
diff --git a/lib/src/main/java/io/v/impl/google/lib/discovery/VScanner.java b/lib/src/main/java/io/v/impl/google/lib/discovery/VScanner.java
index 2172f61..7b6e411 100644
--- a/lib/src/main/java/io/v/impl/google/lib/discovery/VScanner.java
+++ b/lib/src/main/java/io/v/impl/google/lib/discovery/VScanner.java
@@ -9,7 +9,7 @@
 import io.v.impl.google.lib.discovery.ScanHandler;
 
 /**
- * VScanenr wraps a ServiceUUID and a ScanHandler.
+ * Wraps a {@link UUID} and a {@link ScanHandler}.
  */
 public class VScanner {
     private UUID serviceUUID;
diff --git a/lib/src/main/java/io/v/impl/google/lib/discovery/ble/BleAdvertisementConverter.java b/lib/src/main/java/io/v/impl/google/lib/discovery/ble/BleAdvertisementConverter.java
index a94339d..fc1de67 100644
--- a/lib/src/main/java/io/v/impl/google/lib/discovery/ble/BleAdvertisementConverter.java
+++ b/lib/src/main/java/io/v/impl/google/lib/discovery/ble/BleAdvertisementConverter.java
@@ -22,19 +22,19 @@
 import io.v.x.ref.lib.discovery.plugins.ble.Constants;
 
 /**
- * BleAdvertisementConverter converts from io.v.impl.google.lib.discovery.Advertisement to
- * the UUID gatt Services and vice-versa.
+ * BleAdvertisementConverter converts from {@link Advertisement} to
+ * the gatt Services and vice-versa.
  */
 public class BleAdvertisementConverter {
     private static Charset utf8 = Charset.forName("UTF-8");
 
     /**
-     * Converts from io.v.impl.google.lib.discovery.Advertisement to the ble representation.
-     * @param adv The Vanadium Advertisement
-     * @return Map of Characteristic UUIDs to their values.
+     * Converts from {@link Advertisement} to the ble representation.
+     *
+     * @return map of Characteristic UUIDs to their values.
      * @throws IOException
      */
-    public static Map<UUID, byte[]> vadvertismentToBleAttr(Advertisement adv)
+    public static Map<UUID, byte[]> vAdvertismentToBleAttr(Advertisement adv)
             throws IOException {
         Map<UUID, byte[]> attr = new HashMap<>();
         Service service = adv.getService();
@@ -65,10 +65,11 @@
     }
 
     /**
-     * Converts from Map of Characteristic UUIDs to their values to a
-     * io.v.impl.google.lib.discovery.Advertisement.
-     * @param attr The map of characteristic uuids to their values
-     * @return The Vanadium Advertisement based on characteristics.
+     * Converts from Map of Characteristic UUIDs -> values to a
+     * {@link Advertisement}
+     *
+     * @param attr the map of characteristic uuids to their values
+     * @return the Vanadium Advertisement based on characteristics.
      * @throws IOException
      */
     public static Advertisement bleAttrToVAdvertisement(Map<UUID, byte[]> attr)
@@ -110,7 +111,7 @@
         return new Advertisement(
                 new Service(instanceId, instanceName, interfaceName, new Attributes(cleanAttrs),
                         addrs),
-                UUIDUtil.UUIDtUuid(UUIDUtil.UUIDForInterfaceName(interfaceName)),
+                UUIDUtil.UUIDToUuid(UUIDUtil.UUIDForInterfaceName(interfaceName)),
                 new EncryptionAlgorithm(encryptionAlgo),
                 encryptionKeys,
                 false);
diff --git a/lib/src/main/java/io/v/v23/vom/BinaryUtil.java b/lib/src/main/java/io/v/v23/vom/BinaryUtil.java
index 1a73d90..e739dbb 100644
--- a/lib/src/main/java/io/v/v23/vom/BinaryUtil.java
+++ b/lib/src/main/java/io/v/v23/vom/BinaryUtil.java
@@ -15,7 +15,7 @@
 /**
  * Binary encoding and decoding routines.
  */
-final class BinaryUtil {
+public final class BinaryUtil {
     /**
      * Every binary stream starts with this magic byte, to distinguish the binary encoding from
      * the JSON encoding. Note that every valid JSON encoding must start with an ASCII character,or
diff --git a/lib/src/test/java/io/v/impl/google/lib/discovery/DeviceCacheTest.java b/lib/src/test/java/io/v/impl/google/lib/discovery/DeviceCacheTest.java
index 29c4d22..5cf666e 100644
--- a/lib/src/test/java/io/v/impl/google/lib/discovery/DeviceCacheTest.java
+++ b/lib/src/test/java/io/v/impl/google/lib/discovery/DeviceCacheTest.java
@@ -17,15 +17,11 @@
 import io.v.x.ref.lib.discovery.Uuid;
 
 /**
- * Created by bjornick on 10/12/15.
+ * Test for {@link DeviceCache}
  */
 public class DeviceCacheTest extends TestCase {
     private abstract class CountingHandler implements ScanHandler {
-
-        protected int mNumCalls;
-        CountingHandler() {
-            mNumCalls = 0;
-        }
+        protected int mNumCalls = 0;
 
         @Override
         public void handleUpdate(Advertisement adv) {}
@@ -64,7 +60,7 @@
 
         Service service1 = new Service();
         service1.setInterfaceName("randomInterface");
-        Uuid uuid1 = UUIDUtil.UUIDtUuid(UUID.randomUUID());
+        Uuid uuid1 = UUIDUtil.UUIDToUuid(UUID.randomUUID());
         final Advertisement adv1 = new Advertisement(service1, uuid1, new EncryptionAlgorithm(0), null, false);
         advs.add(adv1);
 
@@ -77,11 +73,11 @@
             }
         };
 
-        cache.addScanner(new VScanner(UUIDUtil.UuidtUUID(uuid1), handler));
+        cache.addScanner(new VScanner(UUIDUtil.UuidToUUID(uuid1), handler));
 
         Service service2 = new Service();
         service1.setInterfaceName("randomInterface2");
-        Uuid uuid2 = UUIDUtil.UUIDtUuid(UUID.randomUUID());
+        Uuid uuid2 = UUIDUtil.UUIDToUuid(UUID.randomUUID());
         Advertisement adv2 = new Advertisement(service2, uuid2, new EncryptionAlgorithm(0), null, false);
         advs.add(adv2);
 
@@ -99,7 +95,7 @@
 
         Service service1 = new Service();
         service1.setInterfaceName("randomInterface");
-        Uuid uuid1 = UUIDUtil.UUIDtUuid(UUID.randomUUID());
+        Uuid uuid1 = UUIDUtil.UUIDToUuid(UUID.randomUUID());
         final Advertisement adv1 = new Advertisement(service1, uuid1, new EncryptionAlgorithm(0), null, false);
 
         advs.add(adv1);
@@ -115,12 +111,12 @@
 
         Service service2 = new Service();
         service1.setInterfaceName("randomInterface2");
-        Uuid uuid2 = UUIDUtil.UUIDtUuid(UUID.randomUUID());
+        Uuid uuid2 = UUIDUtil.UUIDToUuid(UUID.randomUUID());
         Advertisement adv2 = new Advertisement(service2, uuid2, new EncryptionAlgorithm(0), null, false);
         advs.add(adv2);
         cache.saveDevice(hash, advs, "newDevice");
 
-        cache.addScanner(new VScanner(UUIDUtil.UuidtUUID(uuid1), handler));
+        cache.addScanner(new VScanner(UUIDUtil.UuidToUUID(uuid1), handler));
 
         // Make sure that the handler is called;
         assertEquals(1, handler.mNumCalls);
@@ -134,7 +130,7 @@
 
         Service service1 = new Service();
         service1.setInterfaceName("randomInterface");
-        Uuid uuid1 = UUIDUtil.UUIDtUuid(UUID.randomUUID());
+        Uuid uuid1 = UUIDUtil.UUIDToUuid(UUID.randomUUID());
         final Advertisement adv1 = new Advertisement(service1, uuid1, new EncryptionAlgorithm(0), null, false);
         advs.add(adv1);
 
@@ -155,11 +151,11 @@
             }
         };
 
-        cache.addScanner(new VScanner(UUIDUtil.UuidtUUID(uuid1), handler));
+        cache.addScanner(new VScanner(UUIDUtil.UuidToUUID(uuid1), handler));
 
         Service service2 = new Service();
         service2.setInterfaceName("randomInterface2");
-        Uuid uuid2 = UUIDUtil.UUIDtUuid(UUID.randomUUID());
+        Uuid uuid2 = UUIDUtil.UUIDToUuid(UUID.randomUUID());
         Advertisement adv2 = new Advertisement(service2, uuid2, new EncryptionAlgorithm(0), null, false);
         advs.add(adv2);
 
@@ -182,7 +178,7 @@
 
         Service service1 = new Service();
         service1.setInterfaceName("randomInterface");
-        Uuid uuid1 = UUIDUtil.UUIDtUuid(UUID.randomUUID());
+        Uuid uuid1 = UUIDUtil.UUIDToUuid(UUID.randomUUID());
         final Advertisement adv1 = new Advertisement(service1, uuid1, new EncryptionAlgorithm(0), null, false);
         advs.add(adv1);
 
@@ -194,11 +190,11 @@
             }
         };
 
-        cache.addScanner(new VScanner(UUIDUtil.UuidtUUID(uuid1), handler));
+        cache.addScanner(new VScanner(UUIDUtil.UuidToUUID(uuid1), handler));
 
         Service service2 = new Service();
         service2.setInterfaceName("randomInterface2");
-        Uuid uuid2 = UUIDUtil.UUIDtUuid(UUID.randomUUID());
+        Uuid uuid2 = UUIDUtil.UUIDToUuid(UUID.randomUUID());
         Advertisement adv2 = new Advertisement(service2, uuid2, new EncryptionAlgorithm(0), null, false);
         advs.add(adv2);
 
diff --git a/lib/src/test/java/io/v/impl/google/lib/discovery/EncodingUtilTest.java b/lib/src/test/java/io/v/impl/google/lib/discovery/EncodingUtilTest.java
index 0df48de..55a9d35 100644
--- a/lib/src/test/java/io/v/impl/google/lib/discovery/EncodingUtilTest.java
+++ b/lib/src/test/java/io/v/impl/google/lib/discovery/EncodingUtilTest.java
@@ -20,7 +20,7 @@
 import io.v.x.ref.lib.discovery.testdata.PackEncryptionKeysTest;
 
 /**
- * Created by bjornick on 10/8/15.
+ * Test for {@link EncodingUtil}
  */
 public class EncodingUtilTest extends TestCase {
     public void testPackAddresses() throws IOException {
diff --git a/lib/src/test/java/io/v/impl/google/lib/discovery/UUIDUtilTest.java b/lib/src/test/java/io/v/impl/google/lib/discovery/UUIDUtilTest.java
index ad72f92..f9e5db9 100644
--- a/lib/src/test/java/io/v/impl/google/lib/discovery/UUIDUtilTest.java
+++ b/lib/src/test/java/io/v/impl/google/lib/discovery/UUIDUtilTest.java
@@ -14,7 +14,7 @@
 import io.v.x.ref.lib.discovery.testdata.UuidTestData;
 
 /**
- * Created by bjornick on 10/8/15.
+ * Tests for {@link UUIDUtil}
  */
 public class UUIDUtilTest extends TestCase {
     public void testInterfaceNameUUID() {
diff --git a/lib/src/test/java/io/v/impl/google/lib/discovery/ble/BleAdvertisementConverterTest.java b/lib/src/test/java/io/v/impl/google/lib/discovery/ble/BleAdvertisementConverterTest.java
index 771d277..90809d4 100644
--- a/lib/src/test/java/io/v/impl/google/lib/discovery/ble/BleAdvertisementConverterTest.java
+++ b/lib/src/test/java/io/v/impl/google/lib/discovery/ble/BleAdvertisementConverterTest.java
@@ -18,7 +18,7 @@
 import io.v.x.ref.lib.discovery.plugins.ble.testdata.Constants;
 
 /**
- * Created by bjornick on 10/9/15.
+ * Tests for {@link BleAdvertisementConverter}
  */
 public class BleAdvertisementConverterTest extends TestCase {
     private static Map<UUID, byte[]> convertBAdv(Map<String, byte[]> in) {
@@ -33,7 +33,7 @@
         // V.init() sets up the jni bindings.
         V.init();
         for (AdvertisementConversionTestCase test : Constants.CONVERSION_TEST_DATA) {
-            Map<UUID, byte[]> res = BleAdvertisementConverter.vadvertismentToBleAttr(
+            Map<UUID, byte[]> res = BleAdvertisementConverter.vAdvertismentToBleAttr(
                     test.getVAdvertisement());
             Map<String, byte[]> want = test.getBleAdvertisement();
             assertEquals(want.size(), res.size());
diff --git a/projects/discovery_sample/app/src/androidTest/java/io/v/discoverysample/ApplicationTest.java b/projects/discovery_sample/app/src/androidTest/java/io/v/discoverysample/ApplicationTest.java
index c6afff2..05649f9 100644
--- a/projects/discovery_sample/app/src/androidTest/java/io/v/discoverysample/ApplicationTest.java
+++ b/projects/discovery_sample/app/src/androidTest/java/io/v/discoverysample/ApplicationTest.java
@@ -1,3 +1,7 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package io.v.discoverysample;
 
 import android.app.Application;
diff --git a/projects/discovery_sample/app/src/main/java/io/v/discoverysample/AttrAdapter.java b/projects/discovery_sample/app/src/main/java/io/v/discoverysample/AttrAdapter.java
index fb0baef..23c0947 100644
--- a/projects/discovery_sample/app/src/main/java/io/v/discoverysample/AttrAdapter.java
+++ b/projects/discovery_sample/app/src/main/java/io/v/discoverysample/AttrAdapter.java
@@ -1,3 +1,7 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package io.v.discoverysample;
 
 import android.content.Context;
diff --git a/projects/discovery_sample/app/src/main/java/io/v/discoverysample/MainActivity.java b/projects/discovery_sample/app/src/main/java/io/v/discoverysample/MainActivity.java
index 9e2546c..affb56a 100644
--- a/projects/discovery_sample/app/src/main/java/io/v/discoverysample/MainActivity.java
+++ b/projects/discovery_sample/app/src/main/java/io/v/discoverysample/MainActivity.java
@@ -1,3 +1,7 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package io.v.discoverysample;
 
 import android.app.Activity;
@@ -94,7 +98,7 @@
         advertisement = new Advertisement(
                 new Service(instanceId, "Android instance",
                         interfaceName, attrs, addrs),
-                UUIDUtil.UUIDtUuid(UUIDUtil.UUIDForInterfaceName(interfaceName)),
+                UUIDUtil.UUIDToUuid(UUIDUtil.UUIDForInterfaceName(interfaceName)),
                 new EncryptionAlgorithm(0),
                 null,
                 false);
diff --git a/projects/discovery_sample/app/src/main/java/io/v/discoverysample/ScanHandlerAdapter.java b/projects/discovery_sample/app/src/main/java/io/v/discoverysample/ScanHandlerAdapter.java
index 24d172a..c6bb1cd 100644
--- a/projects/discovery_sample/app/src/main/java/io/v/discoverysample/ScanHandlerAdapter.java
+++ b/projects/discovery_sample/app/src/main/java/io/v/discoverysample/ScanHandlerAdapter.java
@@ -1,3 +1,7 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package io.v.discoverysample;
 
 import android.app.Activity;