merge in nyc-release history after reset to nyc-dev
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java
index 3a1c907..41c672a 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java
@@ -495,7 +495,7 @@
         @RpcParameter(name = "serviceIndex") Integer serviceIndex,
         @RpcParameter(name = "characteristicUuid") String characteristicUuid,
         @RpcParameter(name = "descriptorUuid") String descriptorUuid,
-        @RpcParameter(name = "value") String value) throws Exception {
+        @RpcParameter(name = "value") byte[] value) throws Exception {
       if (mBluetoothGattList.get(gattIndex) == null) {
         throw new Exception("Invalid gattIndex " + gattIndex);
       }
@@ -518,8 +518,7 @@
       if (gattDescriptor == null) {
         throw new Exception("Invalid descriptor uuid: " + descriptorUuid);
       }
-        byte[] byteArray = ConvertUtils.convertStringToByteArray(value);
-        return gattDescriptor.setValue(byteArray);
+      return gattDescriptor.setValue(value);
     }
 
     /**
@@ -572,7 +571,7 @@
         @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
         @RpcParameter(name = "serviceIndex") Integer serviceIndex,
         @RpcParameter(name = "characteristicUuid") String characteristicUuid,
-        @RpcParameter(name = "value") String value) throws Exception {
+        @RpcParameter(name = "value") byte[] value) throws Exception {
       if (mBluetoothGattList.get(gattIndex) == null) {
         throw new Exception("Invalid gattIndex " + gattIndex);
       }
@@ -590,9 +589,47 @@
       if (gattCharacteristic == null) {
         throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
       }
-      byte[] byteArray = ConvertUtils.convertStringToByteArray(value);
-      return gattCharacteristic.setValue(byteArray);
+      return gattCharacteristic.setValue(value);
     }
+
+    /**
+     * Set write type to a discovered characteristic.
+     * @param gattIndex - the gatt index to use
+     * @param discoveredServiceListIndex - the discovered service list index
+     * @param serviceIndex - the service index of the discoveredServiceListIndex
+     * @param characteristicUuid - the characteristic uuid in which the descriptor is
+     * @param writeType - the write type for characteristic
+     * @return true, if the value was set to the characteristic
+     * @throws Exception
+     */
+    @Rpc(description = "Set write type of a given characteristic to the associated remote device")
+    public boolean gattClientCharacteristicSetWriteType(
+        @RpcParameter(name = "gattIndex") Integer gattIndex,
+        @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
+        @RpcParameter(name = "serviceIndex") Integer serviceIndex,
+        @RpcParameter(name = "characteristicUuid") String characteristicUuid,
+        @RpcParameter(name = "writeType") Integer writeType) throws Exception {
+      if (mBluetoothGattList.get(gattIndex) == null) {
+        throw new Exception("Invalid gattIndex " + gattIndex);
+      }
+      List<BluetoothGattService> discoveredServiceList =
+          mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
+      if (discoveredServiceList == null) {
+        throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
+      }
+      BluetoothGattService gattService = discoveredServiceList.get(serviceIndex);
+      if (gattService == null) {
+        throw new Exception("Invalid serviceIndex " + serviceIndex);
+      }
+      UUID cUuid = UUID.fromString(characteristicUuid);
+      BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid);
+      if (gattCharacteristic == null) {
+        throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
+      }
+      gattCharacteristic.setWriteType(writeType);
+      return true;
+    }
+
     /**
      * Read the RSSI for a connected remote device
      *
@@ -879,6 +916,7 @@
             Log.d("gatt_connect change onCharacteristicRead " + mEventType + " " + index);
             mResults.putInt("Status", status);
             mResults.putString("CharacteristicUuid", characteristic.getUuid().toString());
+            mResults.putByteArray("CharacteristicValue", characteristic.getValue());
             mEventFacade
                     .postEvent(mEventType + index + "onCharacteristicRead", mResults.clone());
             mResults.clear();
@@ -890,6 +928,7 @@
             Log.d("gatt_connect change onCharacteristicWrite " + mEventType + " " + index);
             mResults.putInt("Status", status);
             mResults.putString("CharacteristicUuid", characteristic.getUuid().toString());
+            mResults.putByteArray("CharacteristicValue", characteristic.getValue());
             mEventFacade
                     .postEvent(mEventType + index + "onCharacteristicWrite", mResults.clone());
             mResults.clear();
@@ -901,6 +940,7 @@
             Log.d("gatt_connect change onCharacteristicChanged " + mEventType + " " + index);
             mResults.putInt("ID", index);
             mResults.putString("CharacteristicUuid", characteristic.getUuid().toString());
+            mResults.putByteArray("CharacteristicValue", characteristic.getValue());
             mEventFacade
                     .postEvent(mEventType + index + "onCharacteristicChanged", mResults.clone());
             mResults.clear();
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattServerFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattServerFacade.java
index df03fe2..66f8b7c 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattServerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattServerFacade.java
@@ -129,6 +129,22 @@
   }
 
   /**
+   * Add a service to a bluetooth gatt server
+   *
+   * @param index the bluetooth gatt server to add a service to
+   * @param serviceIndex the service to add to the bluetooth gatt server
+   * @throws Exception
+   */
+  @Rpc(description = "Clear services from bluetooth gatt server")
+  public void gattServerClearServices(@RpcParameter(name = "index") Integer index) throws Exception {
+    if (mBluetoothGattServerList.get(index) != null) {
+        mBluetoothGattServerList.get(index).clearServices();
+    } else {
+      throw new Exception("Invalid index input:" + Integer.toString(index));
+    }
+  }
+
+  /**
    * Get connected devices of the gatt server
    *
    * @param gattServerIndex the gatt server index
@@ -163,7 +179,7 @@
       @RpcParameter(name = "bluetoothDeviceIndex") Integer bluetoothDeviceIndex,
       @RpcParameter(name = "requestId") Integer requestId,
       @RpcParameter(name = "status") Integer status, @RpcParameter(name = "offset") Integer offset,
-      @RpcParameter(name = "value") String value) throws Exception {
+      @RpcParameter(name = "value") byte[] value) throws Exception {
 
     BluetoothGattServer gattServer = mBluetoothGattServerList.get(gattServerIndex);
     if (gattServer == null)
@@ -176,8 +192,43 @@
     if (bluetoothDevice == null)
       throw new Exception(
           "Invalid bluetoothDeviceIndex: " + Integer.toString(bluetoothDeviceIndex));
-    gattServer.sendResponse(bluetoothDevice, requestId, status, offset,
-        ConvertUtils.convertStringToByteArray(value));
+    gattServer.sendResponse(bluetoothDevice, requestId, status, offset, value);
+  }
+
+  /**
+   * Notify that characteristic was changed
+   *
+   * @param gattServerIndex the gatt server index
+   * @param bluetoothDeviceIndex the remotely connected bluetooth device
+   * @param characteristicIndex characteristic index
+   * @param confirm shall we expect confirmation
+   * @throws Exception
+   */
+  @Rpc(description = "Notify that characteristic was changed.")
+  public void gattServerNotifyCharacteristicChanged(
+      @RpcParameter(name = "gattServerIndex") Integer gattServerIndex,
+      @RpcParameter(name = "bluetoothDeviceIndex") Integer bluetoothDeviceIndex,
+      @RpcParameter(name = "characteristicIndex") Integer characteristicIndex,
+      @RpcParameter(name = "confirm") Boolean confirm) throws Exception {
+
+    BluetoothGattServer gattServer = mBluetoothGattServerList.get(gattServerIndex);
+    if (gattServer == null)
+      throw new Exception("Invalid gattServerIndex: " + Integer.toString(gattServerIndex));
+    List<BluetoothDevice> connectedDevices = mGattServerDiscoveredDevicesList.get(gattServerIndex);
+    if (connectedDevices == null)
+      throw new Exception(
+          "Connected device list empty for gattServerIndex:" + Integer.toString(gattServerIndex));
+    BluetoothDevice bluetoothDevice = connectedDevices.get(bluetoothDeviceIndex);
+    if (bluetoothDevice == null)
+      throw new Exception(
+          "Invalid bluetoothDeviceIndex: " + Integer.toString(bluetoothDeviceIndex));
+
+    BluetoothGattCharacteristic bluetoothCharacteristic = mCharacteristicList.get(characteristicIndex);
+    if (bluetoothCharacteristic == null)
+      throw new Exception(
+          "Invalid characteristicIndex: " + Integer.toString(characteristicIndex));
+
+    gattServer.notifyCharacteristicChanged(bluetoothDevice, bluetoothCharacteristic, confirm);
   }
 
   /**
@@ -361,6 +412,23 @@
   }
 
   /**
+   * Set value to a bluetooth gatt characteristic
+   *
+   * @param index the bluetooth gatt characteristic
+   * @param value value
+   * @throws Exception
+   */
+  @Rpc(description = "add descriptor to blutooth gatt characteristic")
+  public void gattServerCharacteristicSetValue(@RpcParameter(name = "index") Integer index,
+      @RpcParameter(name = "value") byte[] value) throws Exception {
+    if (mCharacteristicList.get(index) != null) {
+      mCharacteristicList.get(index).setValue(value);
+    } else {
+      throw new Exception("Invalid index input:" + index);
+    }
+  }
+
+  /**
    * Create a new GattCallback object
    *
    * @return the index of the callback object
@@ -436,7 +504,7 @@
       mResults.putParcelable("BluetoothDevice", device);
       mResults.putBoolean("preparedWrite", preparedWrite);
       mResults.putBoolean("responseNeeded", responseNeeded);
-      mResults.putString("value", ConvertUtils.convertByteArrayToString(value));
+      mResults.putByteArray("value", value);
       mResults.putInt("instanceId", characteristic.getInstanceId());
       mResults.putInt("properties", characteristic.getProperties());
       mResults.putString("uuid", characteristic.getUuid().toString());
@@ -470,7 +538,7 @@
       mResults.putParcelable("BluetoothDevice", device);
       mResults.putBoolean("preparedWrite", preparedWrite);
       mResults.putBoolean("responseNeeded", responseNeeded);
-      mResults.putString("value", ConvertUtils.convertByteArrayToString(value));
+      mResults.putByteArray("value", value);
       mResults.putInt("instanceId", descriptor.getInstanceId());
       mResults.putInt("permissions", descriptor.getPermissions());
       mResults.putString("uuid", descriptor.getUuid().toString());
diff --git a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
index 929fd96..1cc7760 100644
--- a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
+++ b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
@@ -266,7 +266,11 @@
             return buildWifiP2pGroup((WifiP2pGroup) data);
         }
         if (data instanceof byte[]) {
-            return Base64Codec.encodeBase64((byte[]) data);
+            JSONArray result = new JSONArray();
+            for (byte b : (byte[]) data) {
+                result.put(b&0xFF);
+            }
+            return result;
         }
         if (data instanceof Object[]) {
             return buildJSONArray((Object[]) data);
diff --git a/Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java b/Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java
index 5c31c34..285e98b 100644
--- a/Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java
+++ b/Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java
@@ -182,6 +182,13 @@
           result[i] = list.getInt(i);
         }
         return result;
+      } else if (type == byte[].class) {
+        JSONArray list = parameters.getJSONArray(index);
+        byte[] result = new byte[list.length()];
+        for (int i = 0; i < list.length(); i++) {
+          result[i] = (byte)list.getInt(i);
+        }
+        return result;
       } else if (type == String[].class) {
         JSONArray list = parameters.getJSONArray(index);
         String[] result = new String[list.length()];
diff --git a/Utils/src/com/googlecode/android_scripting/ConvertUtils.java b/Utils/src/com/googlecode/android_scripting/ConvertUtils.java
index 3e6956d..c7df6e0 100644
--- a/Utils/src/com/googlecode/android_scripting/ConvertUtils.java
+++ b/Utils/src/com/googlecode/android_scripting/ConvertUtils.java
@@ -31,8 +31,10 @@
         byte[] byteArray = new byte[parseString.length];
         if (byteArray.length > 0) {
             for (int i = 0; i < parseString.length; i++) {
-                byte byteValue = Byte.valueOf(parseString[i].trim());
-                byteArray[i] = byteValue;
+                int val = Integer.valueOf(parseString[i].trim());
+                if (val < 0 || val > 255)
+                    throw new java.lang.NumberFormatException("Val must be between 0 and 255");
+                byteArray[i] = (byte)val;
             }
         }
         return byteArray;
@@ -49,10 +51,10 @@
         if (byteArray != null) {
             for (int i = 0; i < byteArray.length; i++) {
                 if ((i + 1) != byteArray.length) {
-                    ret = ret + Byte.valueOf(byteArray[i]) + ",";
+                    ret = ret + Integer.valueOf((byteArray[i]&0xFF)) + ",";
                 }
                 else {
-                    ret = ret + Byte.valueOf(byteArray[i]);
+                    ret = ret + Integer.valueOf((byteArray[i]&0xFF));
                 }
             }
         }