merge in gingerbread-release history after reset to gingerbread
diff --git a/accessorychat/accessorychat.pde b/accessorychat/accessorychat.pde
deleted file mode 100644
index 20a3dee..0000000
--- a/accessorychat/accessorychat.pde
+++ /dev/null
@@ -1,216 +0,0 @@
-#include <Max3421e.h>
-#include <usb.h>
-
-#define USB_ACCESSORY_VENDOR_ID 0x18D1
-#define USB_ACCESSORY_PRODUCT_ID 0x2D00
-
-#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
-#define ACCESSORY_STRING_MANUFACTURER 0
-#define ACCESSORY_STRING_MODEL 1
-#define ACCESSORY_STRING_TYPE 2
-#define ACCESSORY_STRING_VERSION 3
-
-#define ACCESSORY_SEND_STRING 52
-#define ACCESSORY_START 53
-
-MAX3421E Max;
-USB Usb;
-
-void setup();
-void loop();
-
-uint8_t usbBuff[256];
-
-void setup()
-{
-	Serial.begin( 115200 );
-	Serial.print("\r\nStart");
-	Max.powerOn();
-	delay( 200 );
-}
-
-bool isAndroidVendor(USB_DEVICE_DESCRIPTOR *desc)
-{
-	return desc->idVendor == 0x18d1 || desc->idVendor == 0x22B8;
-}
-
-bool isAccessoryDevice(USB_DEVICE_DESCRIPTOR *desc)
-{
-	return desc->idProduct == 0x2D00 || desc->idProduct == 0x2D01;
-}
-
-void sendString(byte addr, int index, char *str)
-{
-	Usb.ctrlReq(addr, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE,
-		    ACCESSORY_SEND_STRING, 0, 0, index, strlen(str) + 1, str);
-
-}
-
-void switchDevice(byte addr)
-{
-	sendString(addr, ACCESSORY_STRING_MANUFACTURER, "Google, Inc.");
-	sendString(addr, ACCESSORY_STRING_MODEL, "AccessoryChat");
-	sendString(addr, ACCESSORY_STRING_TYPE, "Sample Program");
-	sendString(addr, ACCESSORY_STRING_VERSION, "1.0");
-
-	Usb.ctrlReq(addr, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE,
-		    ACCESSORY_START, 0, 0, 0, 0, NULL);
-}
-
-bool findEndpoints(byte addr, EP_RECORD *inEp, EP_RECORD *outEp)
-{
-	int len;
-	byte err;
-	uint8_t *p;
-
-	err = Usb.getConfDescr(addr, 0, 4, 0, (char *)usbBuff);
-	if (err) {
-		Serial.print("Can't get config descriptor length\n");
-		return false;
-	}
-
-	len = usbBuff[2] | ((int)usbBuff[3] << 8);
-	Serial.print("Config Desc Length: ");
-	Serial.println(len, DEC);
-	if (len > sizeof(usbBuff)) {
-		Serial.print("config descriptor too large\n");
-		/* might want to truncate here */
-		return false;
-	}
-
-	err = Usb.getConfDescr(addr, 0, len, 0, (char *)usbBuff);
-	if (err) {
-		Serial.print("Can't get config descriptor\n");
-		return false;
-	}
-
-	p = usbBuff;
-	while (p < (usbBuff + len)){
-		uint8_t descLen = p[0];
-		uint8_t descType = p[1];
-		USB_ENDPOINT_DESCRIPTOR *epDesc;
-		EP_RECORD *ep;
-
-		switch (descType) {
-		case USB_DESCRIPTOR_CONFIGURATION:
-			Serial.print("config desc\n");
-			break;
-
-		case USB_DESCRIPTOR_INTERFACE:
-			Serial.print("interface desc\n");
-			break;
-
-		case USB_DESCRIPTOR_ENDPOINT:
-			epDesc = (USB_ENDPOINT_DESCRIPTOR *)p;
-			if (!inEp->epAddr && (epDesc->bEndpointAddress & 0x80))
-				ep = inEp;
-			else if (!outEp->epAddr)
-				ep = outEp;
-			else
-				ep = NULL;
-
-			if (ep) {
-				ep->epAddr = epDesc->bEndpointAddress;
-				ep->Attr = epDesc->bmAttributes;
-				ep->MaxPktSize = epDesc->wMaxPacketSize;
-				ep->sndToggle = bmSNDTOG0;
-				ep->rcvToggle = bmRCVTOG0;
-			}
-			break;
-
-		default:
-			Serial.print("unkown desc type ");
-			Serial.println( descType, HEX);
-			break;
-		}
-
-		p += descLen;
-	}
-
-	return inEp->epAddr && outEp->epAddr;
-}
-
-EP_RECORD ep_record[ 3 ];  //endpoint record structure for the mouse
-
-
-void doAndroid(void)
-{
-	byte err;
-	byte idle;
-
-	if (findEndpoints(1, &ep_record[1], &ep_record[2])) {
-		Serial.print("inEp: ");
-		Serial.println(ep_record[1].epAddr, HEX);
-		Serial.print("outEp: ");
-		Serial.println(ep_record[2].epAddr, HEX);
-
-		ep_record[0] = *(Usb.getDevTableEntry(0,0));
-		Usb.setDevTableEntry(1, ep_record);
-
-		err = Usb.setConf( 1, 0, 1 );
-		if (err)
-			Serial.print("Can't set config to 1\n");
-
-		Usb.setUsbTaskState( USB_STATE_RUNNING );
-
-		while(1) {
-			int len = Usb.newInTransfer(1, 1, sizeof(usbBuff),
-						    (char *)usbBuff);
-			int i;
-
-			if (len > 0) {
-				for (i = 0; i < len; i++)
-					Serial.print((char)usbBuff[i]);
-				Serial.print('\n');
-			}
-
-			Usb.outTransfer(1, 2, strlen("ping"), "ping");
-		}
-
-	}
-
-}
-
-
-void loop()
-{
-	USB_DEVICE_DESCRIPTOR *devDesc = (USB_DEVICE_DESCRIPTOR *) usbBuff;
-	byte err;
-
-	Max.Task();
-	Usb.Task();
-	if( Usb.getUsbTaskState() >= USB_STATE_CONFIGURING ) {
-		Serial.print("\nDevice addressed... ");
-		Serial.print("Requesting device descriptor.");
-
-		err = Usb.getDevDescr(1, 0, 0x12, (char *) devDesc);
-		if (err) {
-			Serial.print("\nDevice descriptor cannot be retrieved. Program Halted\n");
-			while(1);
-		}
-
-		if (isAndroidVendor(devDesc)) {
-			Serial.print("found android device\n");
-
-			if (isAccessoryDevice(devDesc)) {
-				Serial.print("found android acessory device\n");
-				doAndroid();
-			} else {
-				Serial.print("found possible device. swithcing to serial mode\n");
-				switchDevice(1);
-			}
-		}
-
-		while (Usb.getUsbTaskState() != USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) {
-			Max.Task();
-			Usb.Task();
-
-
-		}
-
-		Serial.print("detached\n");
-
-	}
-
-}
-
diff --git a/demokit/app/Android.mk b/app/Android.mk
similarity index 100%
rename from demokit/app/Android.mk
rename to app/Android.mk
diff --git a/app/AndroidManifest.xml b/app/AndroidManifest.xml
new file mode 100644
index 0000000..6eac59c
--- /dev/null
+++ b/app/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+	package="com.google.android.DemoKit" android:versionCode="1"
+	android:versionName="1.0">
+
+	<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="11" />
+
+	<application android:icon="@drawable/ic_launcher_demokit"
+		android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar">
+		<uses-library android:name="com.android.future.usb.accessory" />
+		<activity android:name=".DemoKitLaunch" android:label="@string/app_name">
+			<intent-filter>
+				<action android:name="android.intent.action.MAIN" />
+				<category android:name="android.intent.category.LAUNCHER" />
+			</intent-filter>
+		</activity>
+		<activity android:name=".DemoKitActivity" android:label="@string/app_name"
+			android:screenOrientation="portrait">
+		</activity>
+		<activity android:name=".DemoKitPhone" android:label="@string/app_name"
+			android:screenOrientation="portrait">
+		</activity>
+		<activity android:name=".DemoKitTablet" android:label="@string/app_name"
+			android:screenOrientation="landscape" android:theme="@android:style/Theme.Holo">
+		</activity>
+		<activity android:name="UsbAccessoryActivity" android:label="DemoKit"
+			android:taskAffinity="" android:launchMode="singleInstance">
+			<intent-filter>
+				<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
+			</intent-filter>
+
+			<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
+				android:resource="@xml/accessory_filter" />
+		</activity>
+
+	</application>
+</manifest>
\ No newline at end of file
diff --git a/app/res/drawable-hdpi/ic_launcher_demokit.png b/app/res/drawable-hdpi/ic_launcher_demokit.png
new file mode 100644
index 0000000..0de0a95
--- /dev/null
+++ b/app/res/drawable-hdpi/ic_launcher_demokit.png
Binary files differ
diff --git a/app/res/drawable-hdpi/indicator_button1_off_noglow.png b/app/res/drawable-hdpi/indicator_button1_off_noglow.png
new file mode 100644
index 0000000..9cd43ce
--- /dev/null
+++ b/app/res/drawable-hdpi/indicator_button1_off_noglow.png
Binary files differ
diff --git a/app/res/drawable-hdpi/indicator_button1_on_noglow.png b/app/res/drawable-hdpi/indicator_button1_on_noglow.png
new file mode 100644
index 0000000..d24866f
--- /dev/null
+++ b/app/res/drawable-hdpi/indicator_button1_on_noglow.png
Binary files differ
diff --git a/app/res/drawable-hdpi/indicator_button2_off_noglow.png b/app/res/drawable-hdpi/indicator_button2_off_noglow.png
new file mode 100644
index 0000000..92f962f
--- /dev/null
+++ b/app/res/drawable-hdpi/indicator_button2_off_noglow.png
Binary files differ
diff --git a/app/res/drawable-hdpi/indicator_button2_on_noglow.png b/app/res/drawable-hdpi/indicator_button2_on_noglow.png
new file mode 100644
index 0000000..2e24282
--- /dev/null
+++ b/app/res/drawable-hdpi/indicator_button2_on_noglow.png
Binary files differ
diff --git a/app/res/drawable-hdpi/indicator_button3_off_noglow.png b/app/res/drawable-hdpi/indicator_button3_off_noglow.png
new file mode 100644
index 0000000..4f9e951
--- /dev/null
+++ b/app/res/drawable-hdpi/indicator_button3_off_noglow.png
Binary files differ
diff --git a/app/res/drawable-hdpi/indicator_button3_on_noglow.png b/app/res/drawable-hdpi/indicator_button3_on_noglow.png
new file mode 100644
index 0000000..8cfefe6
--- /dev/null
+++ b/app/res/drawable-hdpi/indicator_button3_on_noglow.png
Binary files differ
diff --git a/app/res/drawable-hdpi/indicator_button_capacitive_off_noglow.png b/app/res/drawable-hdpi/indicator_button_capacitive_off_noglow.png
new file mode 100644
index 0000000..ae46086
--- /dev/null
+++ b/app/res/drawable-hdpi/indicator_button_capacitive_off_noglow.png
Binary files differ
diff --git a/app/res/drawable-hdpi/indicator_button_capacitive_on_noglow.png b/app/res/drawable-hdpi/indicator_button_capacitive_on_noglow.png
new file mode 100644
index 0000000..7afc536
--- /dev/null
+++ b/app/res/drawable-hdpi/indicator_button_capacitive_on_noglow.png
Binary files differ
diff --git a/app/res/drawable-hdpi/joystick_background.png b/app/res/drawable-hdpi/joystick_background.png
new file mode 100644
index 0000000..7349fb7
--- /dev/null
+++ b/app/res/drawable-hdpi/joystick_background.png
Binary files differ
diff --git a/app/res/drawable-hdpi/joystick_normal_holo_dark.png b/app/res/drawable-hdpi/joystick_normal_holo_dark.png
new file mode 100644
index 0000000..33796ac
--- /dev/null
+++ b/app/res/drawable-hdpi/joystick_normal_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-hdpi/joystick_pressed_holo_dark.png b/app/res/drawable-hdpi/joystick_pressed_holo_dark.png
new file mode 100644
index 0000000..4eba4b4
--- /dev/null
+++ b/app/res/drawable-hdpi/joystick_pressed_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-hdpi/scrubber_control_holo_dark.png b/app/res/drawable-hdpi/scrubber_control_holo_dark.png
new file mode 100644
index 0000000..5947ee1
--- /dev/null
+++ b/app/res/drawable-hdpi/scrubber_control_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-hdpi/scrubber_horizontal_blue_holo_dark.9.png b/app/res/drawable-hdpi/scrubber_horizontal_blue_holo_dark.9.png
new file mode 100644
index 0000000..1dcd3b0
--- /dev/null
+++ b/app/res/drawable-hdpi/scrubber_horizontal_blue_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-hdpi/scrubber_horizontal_green_holo_dark.9.png b/app/res/drawable-hdpi/scrubber_horizontal_green_holo_dark.9.png
new file mode 100644
index 0000000..6221a0f
--- /dev/null
+++ b/app/res/drawable-hdpi/scrubber_horizontal_green_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-hdpi/scrubber_horizontal_holo_dark.9.png b/app/res/drawable-hdpi/scrubber_horizontal_holo_dark.9.png
new file mode 100644
index 0000000..6a162ed
--- /dev/null
+++ b/app/res/drawable-hdpi/scrubber_horizontal_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-hdpi/scrubber_horizontal_red_holo_dark.9.png b/app/res/drawable-hdpi/scrubber_horizontal_red_holo_dark.9.png
new file mode 100644
index 0000000..b785ebd
--- /dev/null
+++ b/app/res/drawable-hdpi/scrubber_horizontal_red_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-hdpi/scrubber_vertical_blue_holo_dark.9.png b/app/res/drawable-hdpi/scrubber_vertical_blue_holo_dark.9.png
new file mode 100644
index 0000000..5a22af5
--- /dev/null
+++ b/app/res/drawable-hdpi/scrubber_vertical_blue_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-hdpi/scrubber_vertical_green_holo_dark.9.png b/app/res/drawable-hdpi/scrubber_vertical_green_holo_dark.9.png
new file mode 100644
index 0000000..1ebd9f6
--- /dev/null
+++ b/app/res/drawable-hdpi/scrubber_vertical_green_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-hdpi/scrubber_vertical_red_holo_dark.9.png b/app/res/drawable-hdpi/scrubber_vertical_red_holo_dark.9.png
new file mode 100644
index 0000000..74800a4
--- /dev/null
+++ b/app/res/drawable-hdpi/scrubber_vertical_red_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-hdpi/tab_focused_holo_dark.9.png b/app/res/drawable-hdpi/tab_focused_holo_dark.9.png
new file mode 100644
index 0000000..39d0fc1
--- /dev/null
+++ b/app/res/drawable-hdpi/tab_focused_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-hdpi/tab_normal_holo_dark.9.png b/app/res/drawable-hdpi/tab_normal_holo_dark.9.png
new file mode 100644
index 0000000..bf001cf
--- /dev/null
+++ b/app/res/drawable-hdpi/tab_normal_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-hdpi/tab_touched_holo_dark.9.png b/app/res/drawable-hdpi/tab_touched_holo_dark.9.png
new file mode 100644
index 0000000..4c31e32
--- /dev/null
+++ b/app/res/drawable-hdpi/tab_touched_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-hdpi/toggle_button_off_holo_dark.9.png b/app/res/drawable-hdpi/toggle_button_off_holo_dark.9.png
new file mode 100644
index 0000000..52f172c
--- /dev/null
+++ b/app/res/drawable-hdpi/toggle_button_off_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-hdpi/toggle_button_on_holo_dark.9.png b/app/res/drawable-hdpi/toggle_button_on_holo_dark.9.png
new file mode 100644
index 0000000..404f888
--- /dev/null
+++ b/app/res/drawable-hdpi/toggle_button_on_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-mdpi/ic_launcher_demokit.png b/app/res/drawable-mdpi/ic_launcher_demokit.png
new file mode 100644
index 0000000..2111755
--- /dev/null
+++ b/app/res/drawable-mdpi/ic_launcher_demokit.png
Binary files differ
diff --git a/app/res/drawable-mdpi/indicator_button1_off_holo_dark.png b/app/res/drawable-mdpi/indicator_button1_off_holo_dark.png
new file mode 100644
index 0000000..00461f4
--- /dev/null
+++ b/app/res/drawable-mdpi/indicator_button1_off_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-mdpi/indicator_button1_on_holo_dark.png b/app/res/drawable-mdpi/indicator_button1_on_holo_dark.png
new file mode 100644
index 0000000..387fe91
--- /dev/null
+++ b/app/res/drawable-mdpi/indicator_button1_on_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-mdpi/indicator_button2_off_holo_dark.png b/app/res/drawable-mdpi/indicator_button2_off_holo_dark.png
new file mode 100644
index 0000000..186627b
--- /dev/null
+++ b/app/res/drawable-mdpi/indicator_button2_off_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-mdpi/indicator_button2_on_holo_dark.png b/app/res/drawable-mdpi/indicator_button2_on_holo_dark.png
new file mode 100644
index 0000000..8ad4d8c
--- /dev/null
+++ b/app/res/drawable-mdpi/indicator_button2_on_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-mdpi/indicator_button3_off_holo_dark.png b/app/res/drawable-mdpi/indicator_button3_off_holo_dark.png
new file mode 100644
index 0000000..e078642
--- /dev/null
+++ b/app/res/drawable-mdpi/indicator_button3_off_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-mdpi/indicator_button3_on_holo_dark.png b/app/res/drawable-mdpi/indicator_button3_on_holo_dark.png
new file mode 100644
index 0000000..3314451
--- /dev/null
+++ b/app/res/drawable-mdpi/indicator_button3_on_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-mdpi/indicator_button_capacitive_off_holo_dark.png b/app/res/drawable-mdpi/indicator_button_capacitive_off_holo_dark.png
new file mode 100644
index 0000000..6cde802
--- /dev/null
+++ b/app/res/drawable-mdpi/indicator_button_capacitive_off_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-mdpi/indicator_button_capacitive_on_holo_dark.png b/app/res/drawable-mdpi/indicator_button_capacitive_on_holo_dark.png
new file mode 100644
index 0000000..e3fea37
--- /dev/null
+++ b/app/res/drawable-mdpi/indicator_button_capacitive_on_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-mdpi/joystick_background.png b/app/res/drawable-mdpi/joystick_background.png
new file mode 100644
index 0000000..6afdd44
--- /dev/null
+++ b/app/res/drawable-mdpi/joystick_background.png
Binary files differ
diff --git a/app/res/drawable-mdpi/joystick_normal_holo_dark.png b/app/res/drawable-mdpi/joystick_normal_holo_dark.png
new file mode 100644
index 0000000..ab72d36
--- /dev/null
+++ b/app/res/drawable-mdpi/joystick_normal_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-mdpi/joystick_pressed_holo_dark.png b/app/res/drawable-mdpi/joystick_pressed_holo_dark.png
new file mode 100644
index 0000000..c0afa77
--- /dev/null
+++ b/app/res/drawable-mdpi/joystick_pressed_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-mdpi/scrubber_control_holo_dark.png b/app/res/drawable-mdpi/scrubber_control_holo_dark.png
new file mode 100644
index 0000000..90ece2a
--- /dev/null
+++ b/app/res/drawable-mdpi/scrubber_control_holo_dark.png
Binary files differ
diff --git a/app/res/drawable-mdpi/scrubber_horizontal_blue_holo_dark.9.png b/app/res/drawable-mdpi/scrubber_horizontal_blue_holo_dark.9.png
new file mode 100644
index 0000000..3a7665b
--- /dev/null
+++ b/app/res/drawable-mdpi/scrubber_horizontal_blue_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-mdpi/scrubber_horizontal_green_holo_dark.9.png b/app/res/drawable-mdpi/scrubber_horizontal_green_holo_dark.9.png
new file mode 100644
index 0000000..dac988a
--- /dev/null
+++ b/app/res/drawable-mdpi/scrubber_horizontal_green_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-mdpi/scrubber_horizontal_holo_dark.9.png b/app/res/drawable-mdpi/scrubber_horizontal_holo_dark.9.png
new file mode 100644
index 0000000..ce62fbe
--- /dev/null
+++ b/app/res/drawable-mdpi/scrubber_horizontal_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-mdpi/scrubber_horizontal_red_holo_dark.9.png b/app/res/drawable-mdpi/scrubber_horizontal_red_holo_dark.9.png
new file mode 100644
index 0000000..bd349fd
--- /dev/null
+++ b/app/res/drawable-mdpi/scrubber_horizontal_red_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-mdpi/scrubber_vertical_blue_holo_dark.9.png b/app/res/drawable-mdpi/scrubber_vertical_blue_holo_dark.9.png
new file mode 100644
index 0000000..fd9ca52
--- /dev/null
+++ b/app/res/drawable-mdpi/scrubber_vertical_blue_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-mdpi/scrubber_vertical_green_holo_dark.9.png b/app/res/drawable-mdpi/scrubber_vertical_green_holo_dark.9.png
new file mode 100644
index 0000000..f5cc83e
--- /dev/null
+++ b/app/res/drawable-mdpi/scrubber_vertical_green_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-mdpi/scrubber_vertical_red_holo_dark.9.png b/app/res/drawable-mdpi/scrubber_vertical_red_holo_dark.9.png
new file mode 100644
index 0000000..26eaa3d
--- /dev/null
+++ b/app/res/drawable-mdpi/scrubber_vertical_red_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-mdpi/tab_focused_holo_dark.9.png b/app/res/drawable-mdpi/tab_focused_holo_dark.9.png
new file mode 100644
index 0000000..155d0e4
--- /dev/null
+++ b/app/res/drawable-mdpi/tab_focused_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-mdpi/tab_normal_holo_dark.9.png b/app/res/drawable-mdpi/tab_normal_holo_dark.9.png
new file mode 100644
index 0000000..380ffbb
--- /dev/null
+++ b/app/res/drawable-mdpi/tab_normal_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-mdpi/toggle_button_off_holo_dark.9.png b/app/res/drawable-mdpi/toggle_button_off_holo_dark.9.png
new file mode 100644
index 0000000..8cde52c
--- /dev/null
+++ b/app/res/drawable-mdpi/toggle_button_off_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-mdpi/toggle_button_on_holo_dark.9.png b/app/res/drawable-mdpi/toggle_button_on_holo_dark.9.png
new file mode 100644
index 0000000..8ed6cf7
--- /dev/null
+++ b/app/res/drawable-mdpi/toggle_button_on_holo_dark.9.png
Binary files differ
diff --git a/app/res/drawable-nodpi/background_holo_dark.jpg b/app/res/drawable-nodpi/background_holo_dark.jpg
new file mode 100644
index 0000000..97eed62
--- /dev/null
+++ b/app/res/drawable-nodpi/background_holo_dark.jpg
Binary files differ
diff --git a/app/res/drawable-nodpi/demokit_splash.png b/app/res/drawable-nodpi/demokit_splash.png
new file mode 100644
index 0000000..1dbd8e3
--- /dev/null
+++ b/app/res/drawable-nodpi/demokit_splash.png
Binary files differ
diff --git a/app/res/drawable-xlarge-nodpi/background_holo_dark.png b/app/res/drawable-xlarge-nodpi/background_holo_dark.png
new file mode 100644
index 0000000..5d41f1f
--- /dev/null
+++ b/app/res/drawable-xlarge-nodpi/background_holo_dark.png
Binary files differ
diff --git a/app/res/layout-xlarge-land/main.xml b/app/res/layout-xlarge-land/main.xml
new file mode 100644
index 0000000..4ba5569
--- /dev/null
+++ b/app/res/layout-xlarge-land/main.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:orientation="horizontal" android:layout_width="match_parent"
+	android:layout_height="match_parent" android:paddingLeft="20dip"
+	android:paddingBottom="80dip" android:layout_weight="1" android:background="@drawable/background_holo_dark">
+	<include layout="@layout/inputcontainer" android:id="@+id/inputContainer"
+		android:layout_width="400dip" android:layout_height="match_parent"
+		android:layout_weight="0" android:layout_marginRight = "50dip"/>
+	<include layout="@layout/output_tablet" android:id="@+id/outputContainer"
+		android:layout_width="wrap_content" android:layout_height="wrap_content"
+		android:layout_weight="1" />
+</LinearLayout>
diff --git a/app/res/layout/buttoncontainer.xml b/app/res/layout/buttoncontainer.xml
new file mode 100644
index 0000000..117ee2b
--- /dev/null
+++ b/app/res/layout/buttoncontainer.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ButtonContainer"
+	android:paddingLeft="5dip" android:layout_width="fill_parent"
+	android:orientation="vertical" android:layout_height="wrap_content" >
+	<TextView android:text="Buttons" android:id="@+id/lightPercentValue"
+		style="@style/DemoKitControlLabel" android:layout_weight="1"
+		android:layout_height="wrap_content" android:layout_width="wrap_content"
+		android:gravity="center|top"></TextView>
+	<LinearLayout android:id="@+id/ButtonContainer"
+		android:layout_width="fill_parent" android:orientation="horizontal"
+		android:layout_weight="1" android:layout_marginTop="5dip"
+		android:layout_height="wrap_content" android:layout_gravity="center_vertical">
+		<ImageButton android:background="@null" android:id="@+id/Button1"
+			style="@style/DemoKitButtonDisplay" android:src="@drawable/indicator_button1_off_noglow"></ImageButton>
+		<ImageButton android:background="@null" android:id="@+id/Button2"
+			style="@style/DemoKitButtonDisplay" android:src="@drawable/indicator_button2_off_noglow"></ImageButton>
+		<ImageButton android:background="@null" android:id="@+id/Button3"
+			style="@style/DemoKitButtonDisplay" android:src="@drawable/indicator_button3_off_noglow"></ImageButton>
+		<ImageButton android:background="@null" android:id="@+id/Button4"
+			style="@style/DemoKitButtonDisplay" android:src="@drawable/indicator_button_capacitive_off_noglow"></ImageButton>
+	</LinearLayout>
+</LinearLayout>
+
diff --git a/app/res/layout/color_sliders.xml b/app/res/layout/color_sliders.xml
new file mode 100644
index 0000000..0eb670c
--- /dev/null
+++ b/app/res/layout/color_sliders.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="match_parent" android:layout_height="wrap_content"
+	android:orientation="vertical" android:padding="0dip"
+	android:layout_margin="0dip">
+	<include layout="@layout/led_slider"  android:layout_width="match_parent" android:layout_height="wrap_content"/>
+	<include layout="@layout/led_slider"  android:layout_width="match_parent" android:layout_height="wrap_content"/>
+	<include layout="@layout/led_slider"  android:layout_width="match_parent" android:layout_height="wrap_content"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/res/layout/inputcontainer.xml b/app/res/layout/inputcontainer.xml
new file mode 100644
index 0000000..2c2f18f
--- /dev/null
+++ b/app/res/layout/inputcontainer.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="match_parent" android:layout_height="match_parent"
+	android:orientation="vertical" android:weightSum="2">
+	<include layout="@layout/templightcontainer" android:id="@+id/TempLightContainer_ref"
+		android:layout_width="match_parent" android:layout_height="wrap_content"
+		android:layout_weight="1" />
+	<include layout="@layout/buttoncontainer" android:id="@+id/ButtonContainer_ref"
+		android:layout_width="match_parent" android:layout_height="wrap_content"
+		android:layout_weight="1" />
+	<include layout="@layout/joycontainer" android:id="@+id/JoyContainer_ref"
+		android:layout_width="match_parent" android:layout_height="wrap_content"
+		android:layout_weight="0" />
+</LinearLayout>
+
diff --git a/app/res/layout/joycontainer.xml b/app/res/layout/joycontainer.xml
new file mode 100644
index 0000000..ff35579
--- /dev/null
+++ b/app/res/layout/joycontainer.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/JoyContainer"
+	android:layout_width="fill_parent" android:orientation="vertical"
+	android:layout_height="wrap_content" android:paddingLeft="5dip">
+	<TextView android:text="Joystick" android:id="@+id/joystickLabel"
+		android:layout_width="wrap_content" android:layout_height="fill_parent"
+		style="@style/DemoKitControlLabel" android:gravity="center"
+		android:layout_marginTop="10dp" android:layout_marginBottom="-40dp"></TextView>
+	<com.google.android.DemoKit.JoystickView
+		android:id="@+id/joystickView" android:layout_height="wrap_content"
+		android:src="@drawable/joystick_background" android:layout_width="match_parent"
+		android:layout_gravity="center_horizontal|bottom"></com.google.android.DemoKit.JoystickView>
+</LinearLayout>
+
diff --git a/app/res/layout/led_slider.xml b/app/res/layout/led_slider.xml
new file mode 100644
index 0000000..77eed2b
--- /dev/null
+++ b/app/res/layout/led_slider.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="match_parent" android:layout_height="wrap_content"
+	android:orientation="horizontal" android:layout_weight="1">
+	<TextView android:text="@string/ledLabel" style="@style/DemoKitLEDText"
+		android:layout_gravity="left|center_vertical" android:layout_width="40dip" android:clickable="true"/>
+	<com.google.android.DemoKit.Slider
+		android:layout_height="wrap_content" android:layout_width="wrap_content"
+		android:layout_weight="1"></com.google.android.DemoKit.Slider>
+	<TextView android:text="155" style="@style/DemoKitLEDText" android:layout_width="40dip"
+		android:layout_gravity="center_vertical|right"  android:gravity="right" android:clickable="true"/>
+</LinearLayout>
+
diff --git a/app/res/layout/leds_tablet.xml b/app/res/layout/leds_tablet.xml
new file mode 100644
index 0000000..f9f6cfb
--- /dev/null
+++ b/app/res/layout/leds_tablet.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
+	android:orientation="horizontal" android:layout_height="match_parent"  android:layout_weight="1">
+	<include layout="@layout/vertical_color_sliders" android:id="@+id/leds1" android:layout_weight="1"
+		android:layout_width="wrap_content" android:layout_height="wrap_content" />
+	<include layout="@layout/vertical_color_sliders" android:id="@+id/leds2" android:layout_weight="1"
+		android:layout_width="wrap_content" android:layout_height="wrap_content" />
+	<include layout="@layout/vertical_color_sliders" android:id="@+id/leds3" android:layout_weight="1"
+		android:layout_width="wrap_content" android:layout_height="wrap_content" />
+</LinearLayout>
+
diff --git a/app/res/layout/main.xml b/app/res/layout/main.xml
new file mode 100644
index 0000000..1c52750
--- /dev/null
+++ b/app/res/layout/main.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="match_parent" android:layout_height="match_parent"
+	android:orientation="vertical" android:background="@drawable/background_holo_dark">
+	<LinearLayout android:id="@+id/InOutTabContainer"
+		android:layout_width="fill_parent" android:orientation="horizontal"
+		android:layout_height="48dip">
+		<TextView android:layout_width="wrap_content" android:id="@+id/inputLabel"
+			android:text="@string/input" style="@style/DemoKitTextBase"
+			android:gravity="center" android:layout_weight="1"
+			android:background="@drawable/tab_focused_holo_dark"
+			android:clickable="true" android:layout_gravity="center"
+			android:layout_height="match_parent"></TextView>
+		<TextView android:text="@string/output" android:id="@+id/outputLabel"
+			android:layout_width="wrap_content" android:layout_height="match_parent"
+			style="@style/DemoKitTextBase" android:gravity="center"
+			android:layout_weight="1" android:layout_gravity="center"
+			android:clickable="true"></TextView>
+	</LinearLayout>
+	<FrameLayout android:layout_width="match_parent"
+		android:layout_height="wrap_content" android:orientation="vertical"
+		android:paddingLeft="10dip" android:paddingRight="10dip">
+		<include layout="@layout/inputcontainer" android:id="@+id/inputContainer"
+			android:layout_width="match_parent" android:layout_height="wrap_content" />
+		<include layout="@layout/outputcontainer" android:id="@+id/outputContainer"
+			android:layout_width="match_parent" android:layout_height="wrap_content" />
+	</FrameLayout>
+</LinearLayout>
diff --git a/app/res/layout/no_device.xml b/app/res/layout/no_device.xml
new file mode 100644
index 0000000..b8492d4
--- /dev/null
+++ b/app/res/layout/no_device.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="match_parent" android:layout_weight="1"
+	android:layout_height="fill_parent" android:orientation="vertical"
+	android:background="@drawable/background_holo_dark"
+	android:layout_gravity="fill_horizontal">
+	<TextView android:layout_width="match_parent"
+		android:layout_height="wrap_content" android:id="@+id/textView1"
+		android:layout_weight="1" android:text="@string/no_device" style="@style/DemoKitNoDevice"
+		android:gravity="center"></TextView>
+	<ImageView android:id="@+id/imageView1" android:layout_width="match_parent"
+		android:layout_height="wrap_content" android:layout_gravity="fill_vertical"
+		android:src="@drawable/demokit_splash" android:layout_weight="1"></ImageView>
+</LinearLayout>
diff --git a/app/res/layout/output_tablet.xml b/app/res/layout/output_tablet.xml
new file mode 100644
index 0000000..bca2a7b
--- /dev/null
+++ b/app/res/layout/output_tablet.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="match_parent" android:layout_height="wrap_content"
+	android:orientation="vertical" android:layout_weight="1">
+	<include layout="@layout/servo_tablet" android:id="@+id/servo_tablet"
+		android:layout_width="match_parent" android:layout_height="wrap_content"
+		android:layout_weight="0" android:layout_gravity="center_vertical" />
+	<include layout="@layout/relay_tablet" android:layout_width="fill_parent" android:layout_weight="0" 
+		android:layout_height="wrap_content" />
+	<include layout="@layout/leds_tablet" android:layout_width="match_parent" android:layout_weight="1" 
+		android:layout_height="wrap_content" />
+</LinearLayout>
+
diff --git a/app/res/layout/outputcontainer.xml b/app/res/layout/outputcontainer.xml
new file mode 100644
index 0000000..95b8b77
--- /dev/null
+++ b/app/res/layout/outputcontainer.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="match_parent" android:layout_height="wrap_content"
+	android:orientation="vertical" >
+	<include layout="@layout/servorelay" android:id="@+id/servoRelay_ref"
+		android:layout_height="wrap_content" />
+	<include layout="@layout/color_sliders" android:id="@+id/leds1"
+		android:layout_width="match_parent" android:layout_height="wrap_content" />
+	<include layout="@layout/color_sliders" android:id="@+id/leds2"
+		android:layout_width="match_parent" android:layout_height="wrap_content" />
+	<include layout="@layout/color_sliders" android:id="@+id/leds3"
+		android:layout_width="match_parent" android:layout_height="wrap_content" />
+</LinearLayout>
+
diff --git a/app/res/layout/relay_tablet.xml b/app/res/layout/relay_tablet.xml
new file mode 100644
index 0000000..18f229b
--- /dev/null
+++ b/app/res/layout/relay_tablet.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
+	android:orientation="horizontal" android:layout_height="wrap_content">
+	<include android:id="@+id/relay1" layout="@layout/relaybutton"
+		android:layout_width="wrap_content" android:layout_height="wrap_content" />
+	<include android:id="@+id/relay2" layout="@layout/relaybutton"
+		android:layout_width="wrap_content" android:layout_height="wrap_content" />
+</LinearLayout>
+
diff --git a/app/res/layout/relaybutton.xml b/app/res/layout/relaybutton.xml
new file mode 100644
index 0000000..f6b8584
--- /dev/null
+++ b/app/res/layout/relaybutton.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_height="wrap_content" android:orientation="vertical"
+	android:layout_width="wrap_content" android:layout_marginTop="-10dip">
+	<TextView android:text="@string/relay1Label" style="@style/DemoKitControlLabel"
+		android:layout_width="match_parent" android:gravity="left"
+		android:layout_height="wrap_content"></TextView>
+	<ToggleButton style="@style/DemoKitRelayButton"
+		android:textOff="@string/off" android:textOn="@string/on"
+		android:layout_height="wrap_content" android:layout_width="match_parent"></ToggleButton>
+</LinearLayout>
+
diff --git a/app/res/layout/servo.xml b/app/res/layout/servo.xml
new file mode 100644
index 0000000..6444773
--- /dev/null
+++ b/app/res/layout/servo.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="match_parent" android:orientation="vertical"
+	android:layout_height="wrap_content">
+	<TextView android:layout_height="wrap_content" style="@style/DemoKitControlLabel"
+		android:layout_width="wrap_content" android:text="@string/servo1Label"></TextView>
+	<com.google.android.DemoKit.Slider
+		android:layout_height="wrap_content" android:layout_width="match_parent"
+		android:layout_marginTop="-7dip"></com.google.android.DemoKit.Slider>
+</LinearLayout>
+
diff --git a/app/res/layout/servo_tablet.xml b/app/res/layout/servo_tablet.xml
new file mode 100644
index 0000000..23c6ee8
--- /dev/null
+++ b/app/res/layout/servo_tablet.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+	android:layout_width="fill_parent" android:orientation="horizontal"
+	android:layout_height="wrap_content"
+	android:padding="20dip">
+	<include layout="@layout/servo" android:id="@+id/servo1"
+		android:layout_width="fill_parent" android:layout_height="wrap_content"
+		android:layout_weight="1" />
+	<include layout="@layout/servo" android:id="@+id/servo2"
+		android:layout_weight="1" android:layout_width="fill_parent"
+		android:layout_height="wrap_content" />
+	<include layout="@layout/servo" android:id="@+id/servo3"
+		android:layout_weight="1" android:layout_width="fill_parent"
+		android:layout_height="wrap_content" />
+</LinearLayout>
+
diff --git a/app/res/layout/servorelay.xml b/app/res/layout/servorelay.xml
new file mode 100644
index 0000000..6225731
--- /dev/null
+++ b/app/res/layout/servorelay.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/servoRelay" android:layout_width="match_parent"
+	android:orientation="horizontal" android:layout_height="wrap_content">
+	<LinearLayout android:layout_width="0dip"
+		android:layout_height="wrap_content" android:id="@+id/servos"
+		android:orientation="vertical" android:layout_weight="2">
+		<include layout="@layout/servo" android:id="@+id/servo1"
+			android:layout_width="match_parent" android:layout_height="wrap_content"
+			android:layout_weight="0.7" />
+		<include layout="@layout/servo" android:id="@+id/servo2"
+			android:layout_width="match_parent" android:layout_height="wrap_content" />
+		<include layout="@layout/servo" android:id="@+id/servo3"
+			android:layout_width="match_parent" android:layout_height="wrap_content" />
+	</LinearLayout>
+	<LinearLayout android:layout_height="wrap_content"
+		android:id="@+id/relays" android:orientation="vertical"
+		android:layout_width="0dip" android:layout_weight="1" android:padding="-10dip">
+		<include android:id="@+id/relay1" layout="@layout/relaybutton"
+			android:layout_width="wrap_content" android:layout_height="wrap_content" />
+		<include android:id="@+id/relay2" layout="@layout/relaybutton"
+			android:layout_width="wrap_content" android:layout_height="wrap_content" />
+	</LinearLayout>
+</LinearLayout>
+
diff --git a/app/res/layout/templightcontainer.xml b/app/res/layout/templightcontainer.xml
new file mode 100644
index 0000000..d3a2ba1
--- /dev/null
+++ b/app/res/layout/templightcontainer.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/TempLightContainer" android:layout_width="fill_parent"
+	android:orientation="horizontal" android:layout_height="wrap_content"
+	android:paddingLeft="5dip">
+	<LinearLayout android:id="@+id/TempContainer"
+		android:layout_width="fill_parent" android:orientation="vertical"
+		android:layout_weight="1" android:layout_height="wrap_content">
+		<TextView android:id="@+id/tempLabel" android:text="Temp"
+			style="@style/DemoKitControlLabel" android:gravity="center"
+			android:layout_weight="1"></TextView>
+		<TextView android:text="45º" android:id="@+id/tempValue"
+			style="@style/DemoKitMeasurement" android:layout_weight="1"></TextView>
+		<TextView android:text=" " android:id="@+id/hiddenPercentValue"
+			style="@style/DemoKitControlLabel" android:gravity="center"
+			android:layout_weight="1"></TextView>
+	</LinearLayout>
+	<LinearLayout android:id="@+id/LightContainer"
+		android:layout_width="fill_parent" android:orientation="vertical"
+		android:layout_weight="1" android:layout_height="wrap_content">
+		<TextView android:id="@+id/lightPercentLabel" android:text="Light"
+			style="@style/DemoKitControlLabel" android:gravity="center"
+			android:layout_weight="1"></TextView>
+		<LinearLayout android:id="@+id/lightPercentValueContainer"
+			android:layout_width="fill_parent" android:orientation="horizontal"
+			android:layout_height="wrap_content">
+			<TextView android:text="23" android:id="@+id/lightPercentValue"
+				style="@style/DemoKitMeasurement"></TextView>
+			<TextView android:id="@+id/lightPercentSuffix" style="@style/DemoKitMeasurementSuffix"
+				android:gravity="top" android:text="%"></TextView>
+		</LinearLayout>
+		<LinearLayout android:id="@+id/lightRawValueContainer"
+			android:layout_width="wrap_content" android:orientation="horizontal"
+			android:layout_height="wrap_content">
+			<TextView android:text="200" android:id="@+id/lightRawValue"
+				style="@style/DemoKitControlLightLowerLabel"></TextView>
+			<TextView android:text="/1024"
+				style="@style/DemoKitControlLightLowerLabelConst"></TextView>
+		</LinearLayout>
+	</LinearLayout>
+</LinearLayout>
+
diff --git a/app/res/layout/vertical_color_sliders.xml b/app/res/layout/vertical_color_sliders.xml
new file mode 100644
index 0000000..db65e1e
--- /dev/null
+++ b/app/res/layout/vertical_color_sliders.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="match_parent" android:layout_height="wrap_content"
+	android:orientation="horizontal" >
+	<include layout="@layout/vertical_led_slider"
+		android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginRight="20dip"/>
+	<include layout="@layout/vertical_led_slider"
+		android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginRight="20dip"/>
+	<include layout="@layout/vertical_led_slider"
+		android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginRight="20dip"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/res/layout/vertical_led_slider.xml b/app/res/layout/vertical_led_slider.xml
new file mode 100644
index 0000000..a649648
--- /dev/null
+++ b/app/res/layout/vertical_led_slider.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="wrap_content" android:layout_height="match_parent"
+	android:orientation="vertical" android:layout_weight="1" android:layout_marginRight="30dip" android:paddingRight="20dip">
+	<TextView android:text="@string/ledLabel" style="@style/DemoKitLEDText"
+		android:layout_gravity="center" android:layout_height="20dip"
+		android:clickable="true" />
+	<com.google.android.DemoKit.VerticalSlider
+		android:layout_height="wrap_content" android:layout_width="wrap_content"
+		android:layout_weight="1" android:layout_gravity="center">
+	</com.google.android.DemoKit.VerticalSlider>
+		<TextView android:text="155" style="@style/DemoKitLEDText"
+			android:layout_height="20dip" android:layout_gravity="center"
+			android:gravity="center" android:clickable="true" />
+</LinearLayout>
+
diff --git a/app/res/values/attrs.xml b/app/res/values/attrs.xml
new file mode 100644
index 0000000..eeb5e0a
--- /dev/null
+++ b/app/res/values/attrs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<declare-styleable name="com.google.android.DemoKit.Slider">
+		<attr name="vertical" format="boolean" />
+	</declare-styleable>
+</resources> 
diff --git a/app/res/values/colors.xml b/app/res/values/colors.xml
new file mode 100644
index 0000000..c6d917f
--- /dev/null
+++ b/app/res/values/colors.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<color name="DemoKitTextWhite">#FFF</color>
+	<color name="DemoKitLabelGray">#666</color>
+</resources>
diff --git a/app/res/values/strings.xml b/app/res/values/strings.xml
new file mode 100644
index 0000000..740b91e
--- /dev/null
+++ b/app/res/values/strings.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<string name="app_name">DemoKit</string>
+	<string name="input">In</string>
+	<string name="output">Out</string>
+	<string name="no_device">Please connect a DemoKit board.</string>
+	<string name="servo1Label">Servo<sub>1</sub></string>
+	<string name="ledLabel">LED<sub>1</sub></string>
+	<string name="relay1Label">Relay<sub>1</sub></string>
+	<string name="relay2Label">Relay<sub>2</sub></string>
+	<string name="off">Off</string>
+	<string name="on">On</string>
+</resources>
diff --git a/app/res/values/styles.xml b/app/res/values/styles.xml
new file mode 100644
index 0000000..d2f68c7
--- /dev/null
+++ b/app/res/values/styles.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<style name="DemoKitTextBase" parent="@android:style/TextAppearance.Medium">
+		<item name="android:layout_height">wrap_content</item>
+		<item name="android:layout_width">wrap_content</item>
+		<item name="android:typeface">sans</item>
+		<item name="android:textSize">24dip</item>
+		<item name="android:textColor">@color/DemoKitTextWhite</item>
+		<item name="android:background">@null</item>
+		<item name="android:includeFontPadding">false</item>
+	</style>
+	<style name="DemoKitControlLabel" parent="@style/DemoKitTextBase">
+		<item name="android:textSize">15dip</item>
+		<item name="android:textColor">@color/DemoKitLabelGray</item>
+		<item name="android:includeFontPadding">true</item>
+		<item name="android:layout_height">25dip</item>
+		<item name="android:lineSpacingExtra">2dip</item>
+	</style>
+	<style name="DemoKitControlLightLowerLabel" parent="@style/DemoKitTextBase">
+		<item name="android:layout_marginTop">-2dip</item>
+		<item name="android:textSize">15dip</item>
+		<item name="android:textColor">@color/DemoKitTextWhite</item>
+	</style>
+	<style name="DemoKitControlLightLowerLabelConst" parent="@style/DemoKitControlLightLowerLabel">
+		<item name="android:textColor">@color/DemoKitLabelGray</item>
+	</style>
+	<style name="DemoKitMeasurement" parent="@style/DemoKitTextBase">
+		<item name="android:textSize">40dip</item>
+		<item name="android:layout_marginTop">-8dip</item>
+		<item name="android:layout_marginBottom">0dip</item>
+		<item name="android:layout_gravity">top</item>
+	</style>
+	<style name="DemoKitLEDText" parent="@style/DemoKitControlLabel">
+		<item name="android:layout_width">wrap_content</item>
+		<item name="android:layout_height">wrap_content</item>
+	</style>
+	<style name="DemoKitNoDevice" parent="@style/DemoKitTextBase">
+		<item name="android:textSize">30dip</item>
+	</style>
+	<style name="DemoKitMeasurementSuffix" parent="@style/DemoKitMeasurement">
+		<item name="android:textSize">20dip</item>
+	</style>
+	<style name="DemoKitButtonDisplay">
+		<item name="android:layout_height">wrap_content</item>
+		<item name="android:layout_width">wrap_content</item>
+		<item name="android:layout_weight">1</item>
+		<item name="android:gravity">center_horizontal|bottom</item>
+		<item name="android:layout_gravity">center</item>
+		<item name="android:layout_margin">2dip</item>
+		<item name="android:padding">2dip</item>
+	</style>
+	<style name="DemoKitRelayButton" parent="@style/DemoKitTextBase">
+		<item name="android:textSize">15dip</item>
+		<item name="android:layout_marginTop">-10dip</item>
+		<item name="android:layout_height">70dip</item>
+		<item name="android:layout_width">fill_parent</item>
+		<item name="android:textColor">@color/DemoKitTextWhite</item>
+		<item name="android:gravity">center</item>
+		<item name="android:background">@drawable/toggle_button_off_holo_dark</item>
+	</style>
+</resources>
diff --git a/demokit/app/res/xml/accessory_filter.xml b/app/res/xml/accessory_filter.xml
similarity index 100%
rename from demokit/app/res/xml/accessory_filter.xml
rename to app/res/xml/accessory_filter.xml
diff --git a/app/src/com/google/android/DemoKit/AccessoryController.java b/app/src/com/google/android/DemoKit/AccessoryController.java
new file mode 100644
index 0000000..5f94faa
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/AccessoryController.java
@@ -0,0 +1,28 @@
+package com.google.android.DemoKit;
+
+import android.content.res.Resources;
+import android.view.View;
+
+public abstract class AccessoryController {
+
+	protected DemoKitActivity mHostActivity;
+
+	public AccessoryController(DemoKitActivity activity) {
+		mHostActivity = activity;
+	}
+
+	protected View findViewById(int id) {
+		return mHostActivity.findViewById(id);
+	}
+
+	protected Resources getResources() {
+		return mHostActivity.getResources();
+	}
+
+	void accessoryAttached() {
+		onAccesssoryAttached();
+	}
+
+	abstract protected void onAccesssoryAttached();
+
+}
\ No newline at end of file
diff --git a/app/src/com/google/android/DemoKit/BaseActivity.java b/app/src/com/google/android/DemoKit/BaseActivity.java
new file mode 100644
index 0000000..249ad52
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/BaseActivity.java
@@ -0,0 +1,93 @@
+package com.google.android.DemoKit;
+
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+
+public class BaseActivity extends DemoKitActivity {
+
+	private InputController mInputController;
+
+	public BaseActivity() {
+		super();
+	}
+
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		if (mAccessory != null) {
+			showControls();
+		} else {
+			hideControls();
+		}
+	}
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu) {
+		menu.add("Simulate");
+		menu.add("Quit");
+		return true;
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item) {
+		if (item.getTitle() == "Simulate") {
+			showControls();
+		} else if (item.getTitle() == "Quit") {
+			finish();
+			System.exit(0);
+		}
+		return true;
+	}
+
+	protected void enableControls(boolean enable) {
+		if (enable) {
+			showControls();
+		} else {
+			hideControls();
+		}
+	}
+
+	protected void hideControls() {
+		setContentView(R.layout.no_device);
+		mInputController = null;
+	}
+
+	protected void showControls() {
+		setContentView(R.layout.main);
+
+		mInputController = new InputController(this);
+		mInputController.accessoryAttached();
+	}
+
+	protected void handleJoyMessage(JoyMsg j) {
+		if (mInputController != null) {
+			mInputController.joystickMoved(j.getX(), j.getY());
+		}
+	}
+
+	protected void handleLightMessage(LightMsg l) {
+		if (mInputController != null) {
+			mInputController.setLightValue(l.getLight());
+		}
+	}
+
+	protected void handleTemperatureMessage(TemperatureMsg t) {
+		if (mInputController != null) {
+			mInputController.setTemperature(t.getTemperature());
+		}
+	}
+
+	protected void handleSwitchMessage(SwitchMsg o) {
+		if (mInputController != null) {
+			byte sw = o.getSw();
+			if (sw >= 0 && sw < 4) {
+				mInputController.switchStateChanged(sw, o.getState() != 0);
+			} else if (sw == 4) {
+				mInputController
+						.joystickButtonSwitchStateChanged(o.getState() != 0);
+			}
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/app/src/com/google/android/DemoKit/ColorLEDController.java b/app/src/com/google/android/DemoKit/ColorLEDController.java
new file mode 100644
index 0000000..3bc6e24
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/ColorLEDController.java
@@ -0,0 +1,114 @@
+package com.google.android.DemoKit;
+
+import com.google.android.DemoKit.Slider.SliderPositionListener;
+
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.text.SpannableStringBuilder;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.SubscriptSpan;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class ColorLEDController {
+	private int mLEDNumber;
+
+	private Drawable mGreen;
+	private Drawable mRed;
+	private Drawable mBlue;
+	private DemoKitActivity mActivity;
+
+	class LedValueUpdater implements Slider.SliderPositionListener {
+		private TextView mTarget;
+		private final byte mCommandTarget;
+
+		LedValueUpdater(TextView target, int colorIndex) {
+			mTarget = target;
+			mCommandTarget = (byte) ((mLEDNumber - 1) * 3 + colorIndex);
+		}
+
+		public void onPositionChange(double value) {
+			int v = (int) (255 * value);
+			mTarget.setText(String.valueOf(v));
+			if (mActivity != null) {
+				mActivity.sendCommand(DemoKitActivity.LED_SERVO_COMMAND,
+						mCommandTarget, (byte) v);
+			}
+		}
+	}
+
+	class LabelClickListener implements OnClickListener {
+		final private double mValue;
+		private final Slider mSlider;
+
+		public LabelClickListener(Slider slider, double value) {
+			mSlider = slider;
+			mValue = value;
+		}
+
+		public void onClick(View v) {
+			mSlider.setPosition(mValue);
+		}
+
+	}
+
+	public ColorLEDController(DemoKitActivity activity, int number,
+			Resources res, boolean vertical) {
+		mActivity = activity;
+		mLEDNumber = number;
+		if (vertical) {
+			mRed = res.getDrawable(R.drawable.scrubber_vertical_red_holo_dark);
+			mGreen = res
+					.getDrawable(R.drawable.scrubber_vertical_green_holo_dark);
+			mBlue = res
+					.getDrawable(R.drawable.scrubber_vertical_blue_holo_dark);
+		} else {
+			mRed = res
+					.getDrawable(R.drawable.scrubber_horizontal_red_holo_dark);
+			mGreen = res
+					.getDrawable(R.drawable.scrubber_horizontal_green_holo_dark);
+			mBlue = res
+					.getDrawable(R.drawable.scrubber_horizontal_blue_holo_dark);
+		}
+	}
+
+	public void attachToView(ViewGroup targetView) {
+		for (int i = 0; i < 3; ++i) {
+			ViewGroup g = (ViewGroup) targetView.getChildAt(i);
+			TextView label = (TextView) g.getChildAt(0);
+			Slider slider = (Slider) g.getChildAt(1);
+			TextView valueText = (TextView) g.getChildAt(2);
+			SliderPositionListener positionListener = new LedValueUpdater(
+					valueText, i);
+			slider.setPositionListener(positionListener);
+			LabelClickListener leftLabelListener = new LabelClickListener(
+					slider, 0);
+			label.setOnClickListener(leftLabelListener);
+			LabelClickListener rightLabelListener = new LabelClickListener(
+					slider, 1);
+			valueText.setOnClickListener(rightLabelListener);
+			valueText.setText("0");
+			if (i == 0) {
+				String labelText = "Led";
+				SpannableStringBuilder ssb = new SpannableStringBuilder(
+						labelText);
+				ssb.append(String.valueOf(mLEDNumber));
+				int spanStart = labelText.length();
+				int spanEnd = spanStart + 1;
+				ssb.setSpan(new SubscriptSpan(), spanStart, spanEnd, 0);
+				ssb.setSpan(new RelativeSizeSpan(0.7f), spanStart, spanEnd, 0);
+				label.setText(ssb);
+				slider.setSliderBackground(mRed);
+			} else {
+				label.setText("");
+				if (i == 1) {
+					slider.setSliderBackground(mGreen);
+				} else {
+					slider.setSliderBackground(mBlue);
+				}
+			}
+		}
+	}
+}
diff --git a/app/src/com/google/android/DemoKit/ColorWheel.java b/app/src/com/google/android/DemoKit/ColorWheel.java
new file mode 100644
index 0000000..a1292cc
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/ColorWheel.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.DemoKit;
+
+import android.content.Context;
+import android.graphics.*;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+
+/* This class was masterfully pilfered, Carmen-Sandiego style, from our awesome sample app
+ * ApiDemos.  To see how it looks as a dialog, check out:
+ * http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.html
+ *
+ */
+
+  public class ColorWheel extends View {
+      public interface OnColorChangedListener {
+          void colorChanged(int color);
+      }
+
+      /*
+      */
+
+      private OnColorChangedListener mListener;
+
+      private int mInitialColor;
+
+      private Paint mPaint;
+      private Paint mCenterPaint;
+      private final int[] mColors;
+
+      public void setOnColorChangedListener(OnColorChangedListener l) {
+          mListener = l;
+      }
+
+
+      public ColorWheel(Context c, AttributeSet attributes) {
+
+          super(c, attributes);
+
+          mColors = new int[] {
+              0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,
+              0xFFFFFF00, 0xFFFF0000
+          };
+          Shader s = new SweepGradient(0, 0, mColors, null);
+
+          mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+          mPaint.setShader(s);
+          mPaint.setStyle(Paint.Style.STROKE);
+          mPaint.setStrokeWidth(32);
+
+          mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+          mCenterPaint.setColor(0);
+          mCenterPaint.setStrokeWidth(5);
+      }
+
+
+
+      private boolean mTrackingCenter;
+      private boolean mHighlightCenter;
+
+      @Override
+      protected void onDraw(Canvas canvas) {
+          super.onDraw(canvas);
+          float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;
+
+          canvas.translate(CENTER_X, CENTER_X);
+
+          canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
+          canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);
+
+          if (mTrackingCenter) {
+              int c = mCenterPaint.getColor();
+              mCenterPaint.setStyle(Paint.Style.STROKE);
+
+              if (mHighlightCenter) {
+                  mCenterPaint.setAlpha(0xFF);
+              } else {
+                  mCenterPaint.setAlpha(0x80);
+              }
+              canvas.drawCircle(0, 0,
+                                CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
+                                mCenterPaint);
+
+              mCenterPaint.setStyle(Paint.Style.FILL);
+              mCenterPaint.setColor(c);
+          }
+      }
+
+      @Override
+      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+
+          setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
+      }
+
+      private static final int CENTER_X = 200;
+      private static final int CENTER_Y = 200;
+      private static final int CENTER_RADIUS = 64;
+
+      private int floatToByte(float x) {
+          int n = java.lang.Math.round(x);
+          return n;
+      }
+      private int pinToByte(int n) {
+          if (n < 0) {
+              n = 0;
+          } else if (n > 255) {
+              n = 255;
+          }
+          return n;
+      }
+
+      private int ave(int s, int d, float p) {
+          return s + java.lang.Math.round(p * (d - s));
+      }
+
+      private int interpColor(int colors[], float unit) {
+          if (unit <= 0) {
+              return colors[0];
+          }
+          if (unit >= 1) {
+              return colors[colors.length - 1];
+          }
+
+          float p = unit * (colors.length - 1);
+          int i = (int)p;
+          p -= i;
+
+          // now p is just the fractional part [0...1) and i is the index
+          int c0 = colors[i];
+          int c1 = colors[i+1];
+          int a = ave(Color.alpha(c0), Color.alpha(c1), p);
+          int r = ave(Color.red(c0), Color.red(c1), p);
+          int g = ave(Color.green(c0), Color.green(c1), p);
+          int b = ave(Color.blue(c0), Color.blue(c1), p);
+
+          return Color.argb(a, r, g, b);
+      }
+
+      private int rotateColor(int color, float rad) {
+          float deg = rad * 180 / 3.1415927f;
+          int r = Color.red(color);
+          int g = Color.green(color);
+          int b = Color.blue(color);
+
+          ColorMatrix cm = new ColorMatrix();
+          ColorMatrix tmp = new ColorMatrix();
+
+          cm.setRGB2YUV();
+          tmp.setRotate(0, deg);
+          cm.postConcat(tmp);
+          tmp.setYUV2RGB();
+          cm.postConcat(tmp);
+
+          final float[] a = cm.getArray();
+
+          int ir = floatToByte(a[0] * r +  a[1] * g +  a[2] * b);
+          int ig = floatToByte(a[5] * r +  a[6] * g +  a[7] * b);
+          int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);
+
+          return Color.argb(Color.alpha(color), pinToByte(ir),
+                            pinToByte(ig), pinToByte(ib));
+      }
+
+      private static final float PI = 3.1415926f;
+
+      @Override
+      public boolean onTouchEvent(MotionEvent event) {
+          float x = event.getX() - CENTER_X;
+          float y = event.getY() - CENTER_Y;
+          boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;
+
+          switch (event.getAction()) {
+              case MotionEvent.ACTION_DOWN:
+                  mTrackingCenter = inCenter;
+                  if (inCenter) {
+                      mHighlightCenter = true;
+                      invalidate();
+                      break;
+                  }
+              case MotionEvent.ACTION_MOVE:
+                  if (mTrackingCenter) {
+                      if (mHighlightCenter != inCenter) {
+                          mHighlightCenter = inCenter;
+                          invalidate();
+                      }
+                  } else {
+                      float angle = (float)java.lang.Math.atan2(y, x);
+                      // need to turn angle [-PI ... PI] into unit [0....1]
+                      float unit = angle/(2*PI);
+                      if (unit < 0) {
+                          unit += 1;
+                      }
+                      mCenterPaint.setColor(interpColor(mColors, unit));
+                      invalidate();
+                      mListener.colorChanged(mCenterPaint.getColor());
+                  }
+                  break;
+              case MotionEvent.ACTION_UP:
+                  if (mTrackingCenter) {
+                      if (inCenter) {
+                          mListener.colorChanged(mCenterPaint.getColor());
+                      }
+                      mListener.colorChanged(0);
+                      // mListener.colorChanged(mCenterPaint.getColor());
+                      mTrackingCenter = false;    // so we draw w/o halo
+                      invalidate();
+                  }
+                  break;
+          }
+          return true;
+      }
+  }
diff --git a/app/src/com/google/android/DemoKit/ColorWheelLEDController.java b/app/src/com/google/android/DemoKit/ColorWheelLEDController.java
new file mode 100644
index 0000000..82b59b1
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/ColorWheelLEDController.java
@@ -0,0 +1,34 @@
+package com.google.android.DemoKit;
+
+import android.graphics.Color;
+import android.text.SpannableStringBuilder;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.SubscriptSpan;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class ColorWheelLEDController implements ColorWheel.OnColorChangedListener {
+	private DemoKitActivity mActivity;
+
+	public ColorWheelLEDController(DemoKitActivity activity) {
+		mActivity = activity;
+	}
+
+  public void colorChanged(int color) {
+    int red = Color.red(color) / 8;
+    int green = Color.green(color) / 8;
+    int blue = Color.blue(color) / 8;
+
+    mActivity.sendCommand(DemoKitActivity.LED_SERVO_COMMAND,(byte)0,(byte)red);
+    mActivity.sendCommand(DemoKitActivity.LED_SERVO_COMMAND,(byte)1,(byte)green);
+    mActivity.sendCommand(DemoKitActivity.LED_SERVO_COMMAND,(byte)2,(byte)blue);
+
+    mActivity.sendCommand(DemoKitActivity.LED_SERVO_COMMAND,(byte)3,(byte)red);
+    mActivity.sendCommand(DemoKitActivity.LED_SERVO_COMMAND,(byte)4,(byte)green);
+    mActivity.sendCommand(DemoKitActivity.LED_SERVO_COMMAND,(byte)5,(byte)blue);
+
+    mActivity.sendCommand(DemoKitActivity.LED_SERVO_COMMAND,(byte)6,(byte)red);
+    mActivity.sendCommand(DemoKitActivity.LED_SERVO_COMMAND,(byte)7,(byte)green);
+    mActivity.sendCommand(DemoKitActivity.LED_SERVO_COMMAND,(byte)8,(byte)blue);
+  }
+}
diff --git a/app/src/com/google/android/DemoKit/DemoKitActivity.java b/app/src/com/google/android/DemoKit/DemoKitActivity.java
new file mode 100644
index 0000000..de16c1a
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/DemoKitActivity.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.DemoKit;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+import android.widget.SeekBar;
+
+import com.android.future.usb.UsbAccessory;
+import com.android.future.usb.UsbManager;
+
+public class DemoKitActivity extends Activity implements Runnable {
+	private static final String TAG = "DemoKit";
+
+	private static final String ACTION_USB_PERMISSION = "com.google.android.DemoKit.action.USB_PERMISSION";
+
+	private UsbManager mUsbManager;
+	private PendingIntent mPermissionIntent;
+	private boolean mPermissionRequestPending;
+
+	UsbAccessory mAccessory;
+	ParcelFileDescriptor mFileDescriptor;
+	FileInputStream mInputStream;
+	FileOutputStream mOutputStream;
+
+	private static final int MESSAGE_SWITCH = 1;
+	private static final int MESSAGE_TEMPERATURE = 2;
+	private static final int MESSAGE_LIGHT = 3;
+	private static final int MESSAGE_JOY = 4;
+
+	public static final byte LED_SERVO_COMMAND = 2;
+	public static final byte RELAY_COMMAND = 3;
+
+	protected class SwitchMsg {
+		private byte sw;
+		private byte state;
+
+		public SwitchMsg(byte sw, byte state) {
+			this.sw = sw;
+			this.state = state;
+		}
+
+		public byte getSw() {
+			return sw;
+		}
+
+		public byte getState() {
+			return state;
+		}
+	}
+
+	protected class TemperatureMsg {
+		private int temperature;
+
+		public TemperatureMsg(int temperature) {
+			this.temperature = temperature;
+		}
+
+		public int getTemperature() {
+			return temperature;
+		}
+	}
+
+	protected class LightMsg {
+		private int light;
+
+		public LightMsg(int light) {
+			this.light = light;
+		}
+
+		public int getLight() {
+			return light;
+		}
+	}
+
+	protected class JoyMsg {
+		private int x;
+		private int y;
+
+		public JoyMsg(int x, int y) {
+			this.x = x;
+			this.y = y;
+		}
+
+		public int getX() {
+			return x;
+		}
+
+		public int getY() {
+			return y;
+		}
+	}
+
+	private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
+		@Override
+		public void onReceive(Context context, Intent intent) {
+			String action = intent.getAction();
+			if (ACTION_USB_PERMISSION.equals(action)) {
+				synchronized (this) {
+					UsbAccessory accessory = UsbManager.getAccessory(intent);
+					if (intent.getBooleanExtra(
+							UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
+						openAccessory(accessory);
+					} else {
+						Log.d(TAG, "permission denied for accessory "
+								+ accessory);
+					}
+					mPermissionRequestPending = false;
+				}
+			} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
+				UsbAccessory accessory = UsbManager.getAccessory(intent);
+				if (accessory != null && accessory.equals(mAccessory)) {
+					closeAccessory();
+				}
+			}
+		}
+	};
+
+	/** Called when the activity is first created. */
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+
+		mUsbManager = UsbManager.getInstance(this);
+		mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
+				ACTION_USB_PERMISSION), 0);
+		IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
+		filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
+		registerReceiver(mUsbReceiver, filter);
+
+		if (getLastNonConfigurationInstance() != null) {
+			mAccessory = (UsbAccessory) getLastNonConfigurationInstance();
+			openAccessory(mAccessory);
+		}
+
+		setContentView(R.layout.main);
+
+		enableControls(false);
+	}
+
+	@Override
+	public Object onRetainNonConfigurationInstance() {
+		if (mAccessory != null) {
+			return mAccessory;
+		} else {
+			return super.onRetainNonConfigurationInstance();
+		}
+	}
+
+	@Override
+	public void onResume() {
+		super.onResume();
+
+		Intent intent = getIntent();
+		if (mInputStream != null && mOutputStream != null) {
+			return;
+		}
+
+		UsbAccessory[] accessories = mUsbManager.getAccessoryList();
+		UsbAccessory accessory = (accessories == null ? null : accessories[0]);
+		if (accessory != null) {
+			if (mUsbManager.hasPermission(accessory)) {
+				openAccessory(accessory);
+			} else {
+				synchronized (mUsbReceiver) {
+					if (!mPermissionRequestPending) {
+						mUsbManager.requestPermission(accessory,
+								mPermissionIntent);
+						mPermissionRequestPending = true;
+					}
+				}
+			}
+		} else {
+			Log.d(TAG, "mAccessory is null");
+		}
+	}
+
+	@Override
+	public void onPause() {
+		super.onPause();
+		closeAccessory();
+	}
+
+	@Override
+	public void onDestroy() {
+		unregisterReceiver(mUsbReceiver);
+		super.onDestroy();
+	}
+
+	private void openAccessory(UsbAccessory accessory) {
+		mFileDescriptor = mUsbManager.openAccessory(accessory);
+		if (mFileDescriptor != null) {
+			mAccessory = accessory;
+			FileDescriptor fd = mFileDescriptor.getFileDescriptor();
+			mInputStream = new FileInputStream(fd);
+			mOutputStream = new FileOutputStream(fd);
+			Thread thread = new Thread(null, this, "DemoKit");
+			thread.start();
+			Log.d(TAG, "accessory opened");
+			enableControls(true);
+		} else {
+			Log.d(TAG, "accessory open fail");
+		}
+	}
+
+	private void closeAccessory() {
+		enableControls(false);
+
+		try {
+			if (mFileDescriptor != null) {
+				mFileDescriptor.close();
+			}
+		} catch (IOException e) {
+		} finally {
+			mFileDescriptor = null;
+			mAccessory = null;
+		}
+	}
+
+	protected void enableControls(boolean enable) {
+	}
+
+	private int composeInt(byte hi, byte lo) {
+		int val = (int) hi & 0xff;
+		val *= 256;
+		val += (int) lo & 0xff;
+		return val;
+	}
+
+	public void run() {
+		int ret = 0;
+		byte[] buffer = new byte[16384];
+		int i;
+
+		while (ret >= 0) {
+			try {
+				ret = mInputStream.read(buffer);
+			} catch (IOException e) {
+				break;
+			}
+
+			i = 0;
+			while (i < ret) {
+				int len = ret - i;
+
+				switch (buffer[i]) {
+				case 0x1:
+					if (len >= 3) {
+						Message m = Message.obtain(mHandler, MESSAGE_SWITCH);
+						m.obj = new SwitchMsg(buffer[i + 1], buffer[i + 2]);
+						mHandler.sendMessage(m);
+					}
+					i += 3;
+					break;
+
+				case 0x4:
+					if (len >= 3) {
+						Message m = Message.obtain(mHandler,
+								MESSAGE_TEMPERATURE);
+						m.obj = new TemperatureMsg(composeInt(buffer[i + 1],
+								buffer[i + 2]));
+						mHandler.sendMessage(m);
+					}
+					i += 3;
+					break;
+
+				case 0x5:
+					if (len >= 3) {
+						Message m = Message.obtain(mHandler, MESSAGE_LIGHT);
+						m.obj = new LightMsg(composeInt(buffer[i + 1],
+								buffer[i + 2]));
+						mHandler.sendMessage(m);
+					}
+					i += 3;
+					break;
+
+				case 0x6:
+					if (len >= 3) {
+						Message m = Message.obtain(mHandler, MESSAGE_JOY);
+						m.obj = new JoyMsg(buffer[i + 1], buffer[i + 2]);
+						mHandler.sendMessage(m);
+					}
+					i += 3;
+					break;
+
+				default:
+					Log.d(TAG, "unknown msg: " + buffer[i]);
+					i = len;
+					break;
+				}
+			}
+
+		}
+	}
+
+	Handler mHandler = new Handler() {
+		@Override
+		public void handleMessage(Message msg) {
+			switch (msg.what) {
+			case MESSAGE_SWITCH:
+				SwitchMsg o = (SwitchMsg) msg.obj;
+				handleSwitchMessage(o);
+				break;
+
+			case MESSAGE_TEMPERATURE:
+				TemperatureMsg t = (TemperatureMsg) msg.obj;
+				handleTemperatureMessage(t);
+				break;
+
+			case MESSAGE_LIGHT:
+				LightMsg l = (LightMsg) msg.obj;
+				handleLightMessage(l);
+				break;
+
+			case MESSAGE_JOY:
+				JoyMsg j = (JoyMsg) msg.obj;
+				handleJoyMessage(j);
+				break;
+
+			}
+		}
+	};
+
+	public void sendCommand(byte command, byte target, int value) {
+		byte[] buffer = new byte[3];
+		if (value > 255)
+			value = 255;
+
+		buffer[0] = command;
+		buffer[1] = target;
+		buffer[2] = (byte) value;
+		if (mOutputStream != null && buffer[1] != -1) {
+			try {
+				mOutputStream.write(buffer);
+			} catch (IOException e) {
+				Log.e(TAG, "write failed", e);
+			}
+		}
+	}
+
+	protected void handleJoyMessage(JoyMsg j) {
+	}
+
+	protected void handleLightMessage(LightMsg l) {
+	}
+
+	protected void handleTemperatureMessage(TemperatureMsg t) {
+	}
+
+	protected void handleSwitchMessage(SwitchMsg o) {
+	}
+
+	public void onStartTrackingTouch(SeekBar seekBar) {
+	}
+
+	public void onStopTrackingTouch(SeekBar seekBar) {
+	}
+}
diff --git a/app/src/com/google/android/DemoKit/DemoKitLaunch.java b/app/src/com/google/android/DemoKit/DemoKitLaunch.java
new file mode 100644
index 0000000..a2e2e42
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/DemoKitLaunch.java
@@ -0,0 +1,43 @@
+package com.google.android.DemoKit;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Display;
+
+public class DemoKitLaunch extends Activity {
+	static final String TAG = "DemoKitLaunch";
+
+	static Intent createIntent(Activity activity) {
+		Display display = activity.getWindowManager().getDefaultDisplay();
+		int maxExtent = Math.max(display.getWidth(), display.getHeight());
+
+		Intent intent;
+		if (maxExtent > 1200) {
+			Log.i(TAG, "starting tablet ui");
+			intent = new Intent(activity, DemoKitTablet.class);
+		} else {
+			Log.i(TAG, "starting phone ui");
+			intent = new Intent(activity, DemoKitPhone.class);
+		}
+		return intent;
+	}
+	
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+
+		Intent intent = createIntent(this);
+
+		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+				| Intent.FLAG_ACTIVITY_CLEAR_TOP);
+		try {
+			startActivity(intent);
+		} catch (ActivityNotFoundException e) {
+			Log.e(TAG, "unable to start DemoKit activity", e);
+		}
+		finish();
+	}
+}
diff --git a/app/src/com/google/android/DemoKit/DemoKitPhone.java b/app/src/com/google/android/DemoKit/DemoKitPhone.java
new file mode 100644
index 0000000..b429bb3
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/DemoKitPhone.java
@@ -0,0 +1,77 @@
+package com.google.android.DemoKit;
+
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class DemoKitPhone extends BaseActivity implements OnClickListener {
+	static final String TAG = "DemoKitPhone";
+	/** Called when the activity is first created. */
+	TextView mInputLabel;
+	TextView mOutputLabel;
+	LinearLayout mInputContainer;
+	LinearLayout mOutputContainer;
+	Drawable mFocusedTabImage;
+	Drawable mNormalTabImage;
+	OutputController mOutputController;
+
+	@Override
+	protected void hideControls() {
+		super.hideControls();
+		mOutputController = null;
+	}
+
+	public void onCreate(Bundle savedInstanceState) {
+		mFocusedTabImage = getResources().getDrawable(
+				R.drawable.tab_focused_holo_dark);
+		mNormalTabImage = getResources().getDrawable(
+				R.drawable.tab_normal_holo_dark);
+		super.onCreate(savedInstanceState);
+	}
+
+	protected void showControls() {
+		super.showControls();
+
+		mOutputController = new OutputController(this, false);
+		mOutputController.accessoryAttached();
+		mInputLabel = (TextView) findViewById(R.id.inputLabel);
+		mOutputLabel = (TextView) findViewById(R.id.outputLabel);
+		mInputContainer = (LinearLayout) findViewById(R.id.inputContainer);
+		mOutputContainer = (LinearLayout) findViewById(R.id.outputContainer);
+		mInputLabel.setOnClickListener(this);
+		mOutputLabel.setOnClickListener(this);
+
+		showTabContents(true);
+	}
+
+	void showTabContents(Boolean showInput) {
+		if (showInput) {
+			mInputContainer.setVisibility(View.VISIBLE);
+			mInputLabel.setBackgroundDrawable(mFocusedTabImage);
+			mOutputContainer.setVisibility(View.GONE);
+			mOutputLabel.setBackgroundDrawable(mNormalTabImage);
+		} else {
+			mInputContainer.setVisibility(View.GONE);
+			mInputLabel.setBackgroundDrawable(mNormalTabImage);
+			mOutputContainer.setVisibility(View.VISIBLE);
+			mOutputLabel.setBackgroundDrawable(mFocusedTabImage);
+		}
+	}
+
+	public void onClick(View v) {
+		int vId = v.getId();
+		switch (vId) {
+		case R.id.inputLabel:
+			showTabContents(true);
+			break;
+
+		case R.id.outputLabel:
+			showTabContents(false);
+			break;
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/app/src/com/google/android/DemoKit/DemoKitTablet.java b/app/src/com/google/android/DemoKit/DemoKitTablet.java
new file mode 100644
index 0000000..8abe51a
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/DemoKitTablet.java
@@ -0,0 +1,16 @@
+package com.google.android.DemoKit;
+
+public class DemoKitTablet extends BaseActivity {
+	private OutputController mOutputController;
+
+	protected void hideControls() {
+		super.hideControls();
+		mOutputController = null;
+	}
+
+	protected void showControls() {
+		super.showControls();
+		mOutputController = new OutputController(this, true);
+		mOutputController.accessoryAttached();
+	}
+}
diff --git a/app/src/com/google/android/DemoKit/InputController.java b/app/src/com/google/android/DemoKit/InputController.java
new file mode 100644
index 0000000..4c3ad5a
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/InputController.java
@@ -0,0 +1,146 @@
+package com.google.android.DemoKit;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+
+import android.graphics.drawable.Drawable;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class InputController extends AccessoryController {
+	private TextView mTemperature;
+	private TextView mLightView;
+	private TextView mLightRawView;
+	private JoystickView mJoystickView;
+	ArrayList<SwitchDisplayer> mSwitchDisplayers;
+	private final DecimalFormat mLightValueFormatter = new DecimalFormat("##.#");
+	private final DecimalFormat mTemperatureFormatter = new DecimalFormat(
+			"###" + (char)0x00B0);
+
+	InputController(DemoKitActivity hostActivity) {
+		super(hostActivity);
+		mTemperature = (TextView) findViewById(R.id.tempValue);
+		mLightView = (TextView) findViewById(R.id.lightPercentValue);
+		mLightRawView = (TextView) findViewById(R.id.lightRawValue);
+		mJoystickView = (JoystickView) findViewById(R.id.joystickView);
+	}
+
+	protected void onAccesssoryAttached() {
+		mSwitchDisplayers = new ArrayList<SwitchDisplayer>();
+		for (int i = 0; i < 4; ++i) {
+			SwitchDisplayer sd = new SwitchDisplayer(i);
+			mSwitchDisplayers.add(sd);
+		}
+	}
+
+	public void setTemperature(int temperatureFromArduino) {
+		/*
+		 * Arduino board contains a 6 channel (8 channels on the Mini and Nano,
+		 * 16 on the Mega), 10-bit analog to digital converter. This means that
+		 * it will map input voltages between 0 and 5 volts into integer values
+		 * between 0 and 1023. This yields a resolution between readings of: 5
+		 * volts / 1024 units or, .0049 volts (4.9 mV) per unit.
+		 */
+		double voltagemv = temperatureFromArduino * 4.9;
+		/*
+		 * The change in voltage is scaled to a temperature coefficient of 10.0
+		 * mV/degC (typical) for the MCP9700/9700A and 19.5 mV/degC (typical)
+         * for the MCP9701/9701A. The out- put voltage at 0 degC is also scaled
+         * to 500 mV (typical) and 400 mV (typical) for the MCP9700/9700A and
+		 * MCP9701/9701A, respectively. VOUT = TC¥TA+V0degC
+		 */
+		double kVoltageAtZeroCmv = 400;
+		double kTemperatureCoefficientmvperC = 19.5;
+		double ambientTemperatureC = ((double) voltagemv - kVoltageAtZeroCmv)
+				/ kTemperatureCoefficientmvperC;
+		double temperatureF = (9.0 / 5.0) * ambientTemperatureC + 32.0;
+		mTemperature.setText(mTemperatureFormatter.format(temperatureF));
+	}
+
+	public void setLightValue(int lightValueFromArduino) {
+		mLightRawView.setText(String.valueOf(lightValueFromArduino));
+		mLightView.setText(mLightValueFormatter
+				.format((100.0 * (double) lightValueFromArduino / 1024.0)));
+	}
+
+	public void switchStateChanged(int switchIndex, boolean switchState) {
+		if (switchIndex >= 0 && switchIndex < mSwitchDisplayers.size()) {
+			SwitchDisplayer sd = mSwitchDisplayers.get(switchIndex);
+			sd.onSwitchStateChange(switchState);
+		}
+	}
+
+	public void joystickButtonSwitchStateChanged(boolean buttonState) {
+		mJoystickView.setPressed(buttonState);
+	}
+
+	public void joystickMoved(int x, int y) {
+		mJoystickView.setPosition(x, y);
+	}
+
+	public void onTemperature(int temperature) {
+		setTemperature(temperature);
+	}
+
+	public void onLightChange(int lightValue) {
+		setLightValue(lightValue);
+	}
+
+	public void onSwitchStateChange(int switchIndex, Boolean switchState) {
+		switchStateChanged(switchIndex, switchState);
+	}
+
+	public void onButton(Boolean buttonState) {
+		joystickButtonSwitchStateChanged(buttonState);
+	}
+
+	public void onStickMoved(int x, int y) {
+		joystickMoved(x, y);
+	}
+
+	class SwitchDisplayer {
+		private final ImageView mTargetView;
+		private final Drawable mOnImage;
+		private final Drawable mOffImage;
+
+		SwitchDisplayer(int switchIndex) {
+			int viewId, onImageId, offImageId;
+			switch (switchIndex) {
+			default:
+				viewId = R.id.Button1;
+				onImageId = R.drawable.indicator_button1_on_noglow;
+				offImageId = R.drawable.indicator_button1_off_noglow;
+				break;
+			case 1:
+				viewId = R.id.Button2;
+				onImageId = R.drawable.indicator_button2_on_noglow;
+				offImageId = R.drawable.indicator_button2_off_noglow;
+				break;
+			case 2:
+				viewId = R.id.Button3;
+				onImageId = R.drawable.indicator_button3_on_noglow;
+				offImageId = R.drawable.indicator_button3_off_noglow;
+				break;
+			case 3:
+				viewId = R.id.Button4;
+				onImageId = R.drawable.indicator_button_capacitive_on_noglow;
+				offImageId = R.drawable.indicator_button_capacitive_off_noglow;
+				break;
+			}
+			mTargetView = (ImageView) findViewById(viewId);
+			mOffImage = mHostActivity.getResources().getDrawable(offImageId);
+			mOnImage = mHostActivity.getResources().getDrawable(onImageId);
+		}
+
+		public void onSwitchStateChange(Boolean switchState) {
+			Drawable currentImage;
+			if (!switchState) {
+				currentImage = mOffImage;
+			} else {
+				currentImage = mOnImage;
+			}
+			mTargetView.setImageDrawable(currentImage);
+		}
+
+	}
+}
diff --git a/app/src/com/google/android/DemoKit/JoystickView.java b/app/src/com/google/android/DemoKit/JoystickView.java
new file mode 100644
index 0000000..020e276
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/JoystickView.java
@@ -0,0 +1,85 @@
+package com.google.android.DemoKit;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class JoystickView extends View {
+
+	private Drawable mJoystickBackground;
+	private Drawable mJoystickPressed;
+	private Drawable mJoystickNormal;
+
+	private int fX;
+	private int fY;
+	Boolean fPressed;
+	private Paint mLabelPaint;
+	private String mLabelText;
+
+	public JoystickView(Context context) {
+		super(context);
+		initJoystickView(context);
+	}
+
+	public JoystickView(Context context, AttributeSet attrs) {
+		super(context, attrs);
+		initJoystickView(context);
+	}
+
+	public void setPosition(int x, int y) {
+		fX = x;
+		fY = y;
+		mLabelText = String.format("%d,%d", fX, fY);
+		invalidate();
+	}
+
+	public void setPressed(boolean pressed) {
+		fPressed = pressed;
+		invalidate();
+	}
+
+	private void initJoystickView(Context context) {
+		fX = fY = 0;
+		fPressed = false;
+		Resources r = context.getResources();
+		mJoystickBackground = r.getDrawable(R.drawable.joystick_background);
+		int w = mJoystickBackground.getIntrinsicWidth();
+		int h = mJoystickBackground.getIntrinsicHeight();
+		mJoystickBackground.setBounds(0, 0, w, h);
+		mJoystickPressed = r.getDrawable(R.drawable.joystick_pressed_holo_dark);
+		mJoystickNormal = r.getDrawable(R.drawable.joystick_normal_holo_dark);
+		Utilities.centerAround(w / 2 - 4, h / 2 + 4, mJoystickNormal);
+		Utilities.centerAround(w / 2 - 4, h / 2 + 4, mJoystickPressed);
+		mLabelPaint = new Paint();
+		mLabelPaint.setColor(Color.WHITE);
+		mLabelPaint.setTextSize(24);
+		mLabelPaint.setAntiAlias(true);
+		mLabelPaint.setShadowLayer(1, 2, 2, Color.BLACK);
+		setPosition(0, 0);
+	}
+
+	@Override
+	protected void onDraw(Canvas canvas) {
+		mJoystickBackground.draw(canvas);
+		Drawable indicator = fPressed ? mJoystickPressed : mJoystickNormal;
+		int w = mJoystickBackground.getIntrinsicWidth();
+		int h = mJoystickBackground.getIntrinsicHeight();
+		int x = w / 2 - 4 + fX;
+		int y = h / 2 + 4 + fY;
+		Utilities.centerAround(x, y, indicator);
+		indicator.draw(canvas);
+		canvas.drawText(mLabelText, x + 12, y + 8, mLabelPaint);
+	}
+
+	@Override
+	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+		setMeasuredDimension(mJoystickBackground.getIntrinsicWidth(),
+				mJoystickBackground.getIntrinsicHeight());
+	}
+
+}
diff --git a/app/src/com/google/android/DemoKit/OutputController.java b/app/src/com/google/android/DemoKit/OutputController.java
new file mode 100644
index 0000000..a9842b9
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/OutputController.java
@@ -0,0 +1,44 @@
+package com.google.android.DemoKit;
+
+import android.view.ViewGroup;
+
+public class OutputController extends AccessoryController {
+
+	private boolean mVertical;
+
+	OutputController(DemoKitActivity hostActivity, boolean vertical) {
+		super(hostActivity);
+		mVertical = vertical;
+	}
+
+	protected void onAccesssoryAttached() {
+		setupServoController(1, R.id.servo1);
+		setupServoController(2, R.id.servo2);
+		setupServoController(3, R.id.servo3);
+
+		setupLedController(1, R.id.leds1);
+		setupLedController(2, R.id.leds2);
+		setupLedController(3, R.id.leds3);
+
+		setupRelayController(1, R.id.relay1);
+		setupRelayController(2, R.id.relay2);
+	}
+
+	private void setupServoController(int servoIndex, int viewId) {
+		ServoController sc = new ServoController(mHostActivity, servoIndex);
+		sc.attachToView((ViewGroup) findViewById(viewId));
+	}
+
+	private void setupLedController(int index, int viewId) {
+		ColorLEDController ledC = new ColorLEDController(mHostActivity, index,
+				getResources(), mVertical);
+		ledC.attachToView((ViewGroup) findViewById(viewId));
+	}
+
+	private void setupRelayController(int index, int viewId) {
+		RelayController r = new RelayController(mHostActivity, index,
+				getResources());
+		r.attachToView((ViewGroup) findViewById(viewId));
+	}
+
+}
diff --git a/app/src/com/google/android/DemoKit/RelayController.java b/app/src/com/google/android/DemoKit/RelayController.java
new file mode 100644
index 0000000..d08516f
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/RelayController.java
@@ -0,0 +1,56 @@
+package com.google.android.DemoKit;
+
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.text.SpannableStringBuilder;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.SubscriptSpan;
+import android.view.ViewGroup;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.TextView;
+import android.widget.ToggleButton;
+
+public class RelayController implements OnCheckedChangeListener {
+	private final int mRelayNumber;
+	private final byte mCommandTarget;
+	private DemoKitActivity mActivity;
+	private TextView mLabel;
+	private ToggleButton mButton;
+	private Drawable mOffBackground;
+	private Drawable mOnBackground;
+
+	public RelayController(DemoKitActivity activity, int relayNumber,
+			Resources res) {
+		mActivity = activity;
+		mRelayNumber = relayNumber;
+		mCommandTarget = (byte) (relayNumber - 1);
+		mOffBackground = res
+				.getDrawable(R.drawable.toggle_button_off_holo_dark);
+		mOnBackground = res.getDrawable(R.drawable.toggle_button_on_holo_dark);
+	}
+
+	public void attachToView(ViewGroup targetView) {
+		mLabel = (TextView) targetView.getChildAt(0);
+		SpannableStringBuilder ssb = new SpannableStringBuilder("Relay");
+		ssb.append(String.valueOf(mRelayNumber));
+		ssb.setSpan(new SubscriptSpan(), 5, 6, 0);
+		ssb.setSpan(new RelativeSizeSpan(0.7f), 5, 6, 0);
+		mLabel.setText(ssb);
+		mButton = (ToggleButton) targetView.getChildAt(1);
+		mButton.setOnCheckedChangeListener(this);
+	}
+
+	public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
+		if (isChecked) {
+			mButton.setBackgroundDrawable(mOnBackground);
+		} else {
+			mButton.setBackgroundDrawable(mOffBackground);
+		}
+		if (mActivity != null) {
+			mActivity.sendCommand(DemoKitActivity.RELAY_COMMAND,
+					mCommandTarget, isChecked ? 1 : 0);
+		}
+	}
+
+}
diff --git a/app/src/com/google/android/DemoKit/ServoController.java b/app/src/com/google/android/DemoKit/ServoController.java
new file mode 100644
index 0000000..4584a9f
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/ServoController.java
@@ -0,0 +1,39 @@
+package com.google.android.DemoKit;
+
+import android.text.SpannableStringBuilder;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.SubscriptSpan;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class ServoController implements Slider.SliderPositionListener {
+	private final int mServoNumber;
+	private final byte mCommandTarget;
+	private TextView mLabel;
+	private Slider mSlider;
+	private DemoKitActivity mActivity;
+
+	public ServoController(DemoKitActivity activity, int servoNumber) {
+		mActivity = activity;
+		mServoNumber = servoNumber;
+		mCommandTarget = (byte) (servoNumber - 1 + 0x10);
+	}
+
+	public void attachToView(ViewGroup targetView) {
+		mLabel = (TextView) targetView.getChildAt(0);
+		SpannableStringBuilder ssb = new SpannableStringBuilder("Servo");
+		ssb.append(String.valueOf(mServoNumber));
+		ssb.setSpan(new SubscriptSpan(), 5, 6, 0);
+		ssb.setSpan(new RelativeSizeSpan(0.7f), 5, 6, 0);
+		mLabel.setText(ssb);
+		mSlider = (Slider) targetView.getChildAt(1);
+		mSlider.setPositionListener(this);
+	}
+
+	public void onPositionChange(double value) {
+		byte v = (byte) (value * 255);
+		mActivity.sendCommand(DemoKitActivity.LED_SERVO_COMMAND,
+				mCommandTarget, v);
+	}
+
+}
diff --git a/app/src/com/google/android/DemoKit/Slider.java b/app/src/com/google/android/DemoKit/Slider.java
new file mode 100644
index 0000000..3517bff
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/Slider.java
@@ -0,0 +1,133 @@
+package com.google.android.DemoKit;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class Slider extends View {
+
+	interface SliderPositionListener {
+		void onPositionChange(double value);
+	}
+
+	private Drawable mIndicator;
+	private Drawable mBackground;
+	private double mPosition;
+	private SliderPositionListener mListener;
+	private boolean mVertical;
+
+	public Slider(Context context) {
+		super(context);
+		initSliderView(context, false);
+	}
+
+	public Slider(Context context, AttributeSet attrs) {
+		super(context, attrs);
+		initSliderView(context, false);
+	}
+
+	public void setSliderBackground(Drawable background) {
+		mBackground = background;
+		invalidate();
+	}
+
+	public void setPositionListener(SliderPositionListener listener) {
+		mListener = listener;
+	}
+
+	public void setPosition(double position) {
+		if (mPosition != position) {
+			invalidate();
+			mPosition = position;
+			if (mListener != null) {
+				mListener.onPositionChange(mPosition);
+			}
+		}
+	}
+
+	private OnTouchListener mClickListener = new OnTouchListener() {
+		public boolean onTouch(View v, MotionEvent m) {
+			Rect r = new Rect();
+			getDrawingRect(r);
+
+			double position;
+			if (mVertical) {
+				double y = m.getY();
+				position = Math.max(0, (r.bottom - y) / r.height());
+			} else {
+				double x = m.getX();
+				position = Math.max(0, (x - r.left) / r.width());
+			}
+			position = Math.min(1, position);
+			setPosition(position);
+			return true;
+		}
+	};
+
+	protected void initSliderView(Context context, boolean vertical) {
+		mPosition = 0;
+		mVertical = vertical;
+		Resources res = context.getResources();
+		if (mVertical) {
+			mBackground = res
+					.getDrawable(R.drawable.scrubber_vertical_blue_holo_dark);
+		} else {
+			mBackground = res
+					.getDrawable(R.drawable.scrubber_horizontal_holo_dark);
+		}
+		mIndicator = res.getDrawable(R.drawable.scrubber_control_holo_dark);
+		this.setOnTouchListener(mClickListener);
+	}
+
+	protected void onDraw(Canvas canvas) {
+		Rect r = new Rect();
+		getDrawingRect(r);
+		if (mVertical) {
+			int lineX = r.centerX();
+			int bgW = mBackground.getIntrinsicWidth() / 2;
+			if (bgW == 0) {
+				bgW = 5;
+			}
+			mBackground.setBounds(lineX - bgW, r.top + 10, lineX + bgW,
+					r.bottom - 10);
+			mBackground.draw(canvas);
+			final int kMargin = 48;
+			int indicatorY = (int) (r.bottom - (r.height() - kMargin)
+					* mPosition)
+					- kMargin / 2;
+			Utilities.centerAround(lineX, indicatorY, mIndicator);
+			mIndicator.draw(canvas);
+		} else {
+			int lineY = r.centerY();
+			int bgH = mBackground.getIntrinsicHeight() / 2;
+			if (bgH == 0) {
+				bgH = 5;
+			}
+			mBackground.setBounds(r.left + 10, lineY - bgH, r.right - 10, lineY
+					+ bgH);
+			mBackground.draw(canvas);
+			final int kMargin = 48;
+			int indicatorX = (int) ((r.width() - kMargin) * mPosition) + r.left
+					+ kMargin / 2;
+			Utilities.centerAround(indicatorX, lineY, mIndicator);
+			mIndicator.draw(canvas);
+		}
+	}
+
+	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+		if (mVertical) {
+			setMeasuredDimension(mIndicator.getIntrinsicWidth(),
+					getMeasuredHeight());
+		} else {
+			setMeasuredDimension(getMeasuredWidth(),
+					mIndicator.getIntrinsicHeight());
+		}
+	}
+
+}
diff --git a/demokit/app/src/com/google/DemoKit/UsbAccessoryActivity.java b/app/src/com/google/android/DemoKit/UsbAccessoryActivity.java
similarity index 64%
rename from demokit/app/src/com/google/DemoKit/UsbAccessoryActivity.java
rename to app/src/com/google/android/DemoKit/UsbAccessoryActivity.java
index d451e38..9bf4079 100644
--- a/demokit/app/src/com/google/DemoKit/UsbAccessoryActivity.java
+++ b/app/src/com/google/android/DemoKit/UsbAccessoryActivity.java
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.DemoKit;
-
+package com.google.android.DemoKit;
 
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
@@ -28,19 +27,20 @@
  */
 public final class UsbAccessoryActivity extends Activity {
 
-    static final String TAG = "UsbAccessoryActivity";
+	static final String TAG = "UsbAccessoryActivity";
 
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
 
-        Intent intent = new Intent(this, DemoKitActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        try {
-            startActivity(intent);
-        } catch (ActivityNotFoundException e) {
-            Log.e(TAG, "unable to start DemoKit activity", e);
-        }
-        finish();
-    }
+		Intent intent = DemoKitLaunch.createIntent(this);
+		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+				| Intent.FLAG_ACTIVITY_CLEAR_TOP);
+		try {
+			startActivity(intent);
+		} catch (ActivityNotFoundException e) {
+			Log.e(TAG, "unable to start DemoKit activity", e);
+		}
+		finish();
+	}
 }
diff --git a/app/src/com/google/android/DemoKit/Utilities.java b/app/src/com/google/android/DemoKit/Utilities.java
new file mode 100644
index 0000000..0e9679c
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/Utilities.java
@@ -0,0 +1,16 @@
+package com.google.android.DemoKit;
+
+import android.graphics.drawable.Drawable;
+
+public class Utilities {
+	static void centerAround(int x, int y, Drawable d) {
+		int w = d.getIntrinsicWidth();
+		int h = d.getIntrinsicHeight();
+		int left = x - w / 2;
+		int top = y - h / 2;
+		int right = left + w;
+		int bottom = top + h;
+		d.setBounds(left, top, right, bottom);
+	}
+
+}
diff --git a/app/src/com/google/android/DemoKit/VerticalSlider.java b/app/src/com/google/android/DemoKit/VerticalSlider.java
new file mode 100644
index 0000000..4cbb768
--- /dev/null
+++ b/app/src/com/google/android/DemoKit/VerticalSlider.java
@@ -0,0 +1,17 @@
+package com.google.android.DemoKit;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+public class VerticalSlider extends Slider {
+	public VerticalSlider(Context context) {
+		super(context);
+		initSliderView(context, true);
+	}
+
+	public VerticalSlider(Context context, AttributeSet attrs) {
+		super(context, attrs);
+		initSliderView(context, true);
+	}
+
+}
diff --git a/demokit/app/AndroidManifest.xml b/demokit/app/AndroidManifest.xml
deleted file mode 100644
index d873887..0000000
--- a/demokit/app/AndroidManifest.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="com.google.DemoKit"
-      android:versionCode="1"
-      android:versionName="1.0">
-
-  <uses-sdk android:targetSdkVersion="11" />
-
-    <application android:label="DemoKit"
-            android:icon="@drawable/icon"
-            android:hardwareAccelerated="true">
-        <uses-library android:name="com.android.future.usb.accessory" />
-
-        <activity android:name="DemoKitActivity"
-                  android:label="DemoKit">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-
-        <!-- This activity receives USB_ACCESSORY_ATTACHED Intents and springboards to main Gallery activity. -->
-        <activity android:name="UsbAccessoryActivity" android:label="DemoKit"
-                android:taskAffinity=""
-                android:launchMode="singleInstance">
-            <intent-filter>
-                <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
-            </intent-filter>
-
-            <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
-                android:resource="@xml/accessory_filter" />
-        </activity>
-
-    </application>
-</manifest>
diff --git a/demokit/app/res/drawable-hdpi/droid_off.png b/demokit/app/res/drawable-hdpi/droid_off.png
deleted file mode 100644
index c908bf8..0000000
--- a/demokit/app/res/drawable-hdpi/droid_off.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-hdpi/droid_on.png b/demokit/app/res/drawable-hdpi/droid_on.png
deleted file mode 100644
index 0bd2390..0000000
--- a/demokit/app/res/drawable-hdpi/droid_on.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-hdpi/greenball.png b/demokit/app/res/drawable-hdpi/greenball.png
deleted file mode 100644
index 7851232..0000000
--- a/demokit/app/res/drawable-hdpi/greenball.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-hdpi/icon.png b/demokit/app/res/drawable-hdpi/icon.png
deleted file mode 100644
index 0496e35..0000000
--- a/demokit/app/res/drawable-hdpi/icon.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-hdpi/redball.png b/demokit/app/res/drawable-hdpi/redball.png
deleted file mode 100644
index fba2f5d..0000000
--- a/demokit/app/res/drawable-hdpi/redball.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-ldpi/droid_off.png b/demokit/app/res/drawable-ldpi/droid_off.png
deleted file mode 100644
index 75a1bf6..0000000
--- a/demokit/app/res/drawable-ldpi/droid_off.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-ldpi/droid_on.png b/demokit/app/res/drawable-ldpi/droid_on.png
deleted file mode 100644
index 41dd449..0000000
--- a/demokit/app/res/drawable-ldpi/droid_on.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-ldpi/greenball.png b/demokit/app/res/drawable-ldpi/greenball.png
deleted file mode 100644
index 3a814fc..0000000
--- a/demokit/app/res/drawable-ldpi/greenball.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-ldpi/icon.png b/demokit/app/res/drawable-ldpi/icon.png
deleted file mode 100644
index ee36e96..0000000
--- a/demokit/app/res/drawable-ldpi/icon.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-ldpi/redball.png b/demokit/app/res/drawable-ldpi/redball.png
deleted file mode 100644
index 6e0add3..0000000
--- a/demokit/app/res/drawable-ldpi/redball.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-mdpi/droid_off.png b/demokit/app/res/drawable-mdpi/droid_off.png
deleted file mode 100644
index e7fcabf..0000000
--- a/demokit/app/res/drawable-mdpi/droid_off.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-mdpi/droid_on.png b/demokit/app/res/drawable-mdpi/droid_on.png
deleted file mode 100644
index 121f517..0000000
--- a/demokit/app/res/drawable-mdpi/droid_on.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-mdpi/greenball.png b/demokit/app/res/drawable-mdpi/greenball.png
deleted file mode 100644
index 7851232..0000000
--- a/demokit/app/res/drawable-mdpi/greenball.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-mdpi/icon.png b/demokit/app/res/drawable-mdpi/icon.png
deleted file mode 100644
index b01345c..0000000
--- a/demokit/app/res/drawable-mdpi/icon.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/drawable-mdpi/redball.png b/demokit/app/res/drawable-mdpi/redball.png
deleted file mode 100644
index fba2f5d..0000000
--- a/demokit/app/res/drawable-mdpi/redball.png
+++ /dev/null
Binary files differ
diff --git a/demokit/app/res/layout/main.xml b/demokit/app/res/layout/main.xml
deleted file mode 100644
index 4becaa0..0000000
--- a/demokit/app/res/layout/main.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-    <TableLayout android:id="@+id/tableLayout1" android:layout_width="match_parent" android:layout_height="wrap_content" android:addStatesFromChildren="true">
-        <TableRow android:id="@+id/tableRow1" android:layout_width="match_parent" android:layout_gravity="center_vertical" android:orientation="vertical" android:showDividers="beginning|middle|end" android:layout_weight="1" android:layout_height="wrap_content" android:baselineAligned="false" android:gravity="center_vertical" android:layout_marginBottom="8dip">
-            <TextView android:id="@+id/textView17" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/buttons" android:layout_marginRight="8dip"></TextView>
-            <LinearLayout android:id="@+id/linearLayout1" android:layout_height="wrap_content" android:verticalScrollbarPosition="right" android:layout_width="match_parent" android:layout_gravity="fill_horizontal">
-                <TextView android:id="@+id/textView1" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="@string/button1" android:layout_gravity="center_vertical" android:layout_marginRight="8dip"></TextView>
-                <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/droid_off" android:id="@+id/button1Image"></ImageView>
-            </LinearLayout>
-            <LinearLayout android:id="@+id/linearLayout5" android:layout_width="wrap_content" android:layout_height="wrap_content">
-                <TextView android:layout_width="wrap_content" android:id="@+id/textView2" android:layout_height="wrap_content" android:text="@string/button2" android:layout_gravity="center_vertical" android:layout_marginRight="8dip"></TextView>
-                <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/droid_off" android:id="@+id/button2Image"></ImageView>
-            </LinearLayout>
-            <LinearLayout android:id="@+id/linearLayout6" android:layout_width="wrap_content" android:layout_height="wrap_content">
-                <TextView android:layout_width="wrap_content" android:id="@+id/textView3" android:layout_height="wrap_content" android:text="@string/button3" android:layout_gravity="center_vertical" android:layout_marginRight="8dip"></TextView>
-                <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/droid_off" android:id="@+id/button3Image"></ImageView>
-            </LinearLayout>
-        </TableRow>
-        <TableRow android:id="@+id/tableRow14" android:layout_width="wrap_content" android:layout_height="wrap_content">
-            <TextView android:id="@+id/textView19" android:layout_height="wrap_content" android:layout_width="wrap_content"></TextView>
-            <TextView android:id="@+id/textView20" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_gravity="center_horizontal" android:text="@string/led1"></TextView>
-            <TextView android:layout_gravity="center_horizontal" android:id="@+id/textView21" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/led2"></TextView>
-            <TextView android:layout_gravity="center_horizontal" android:id="@+id/textView22" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/led3"></TextView>
-        </TableRow>
-        <TableRow android:layout_height="wrap_content" android:id="@+id/tableRow4" android:layout_width="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:layout_marginBottom="8dip">
-            <TextView android:id="@+id/textView5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dip" android:text="@string/red"></TextView>
-            <SeekBar android:layout_height="wrap_content" android:max="255" android:id="@+id/led1Red" android:layout_marginRight="16dip" android:layout_width="250dip"></SeekBar>
-            <SeekBar android:id="@+id/led2Red" android:layout_height="wrap_content" android:max="255" android:layout_marginRight="16dip" android:layout_width="250dip"></SeekBar>
-            <SeekBar android:id="@+id/led3Red" android:layout_height="wrap_content" android:max="255" android:layout_marginRight="16dip" android:layout_width="250dip"></SeekBar>
-        </TableRow>
-        <TableRow android:layout_height="wrap_content" android:id="@+id/tableRow5" android:layout_width="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:layout_marginBottom="8dip">
-            <TextView android:id="@+id/textView6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dip" android:text="@string/green"></TextView>
-            <SeekBar android:layout_height="wrap_content" android:max="255" android:id="@+id/led1Green" android:layout_marginRight="16dip" android:layout_width="250dip"></SeekBar>
-            <SeekBar android:id="@+id/led2Green" android:layout_height="wrap_content" android:max="255" android:layout_marginRight="16dip" android:layout_width="250dip"></SeekBar>
-            <SeekBar android:id="@+id/led3Green" android:layout_height="wrap_content" android:max="255" android:layout_marginRight="16dip" android:layout_width="250dip"></SeekBar>
-        </TableRow>
-        <TableRow android:layout_height="wrap_content" android:id="@+id/tableRow6" android:layout_width="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:layout_marginBottom="8dip">
-            <TextView android:id="@+id/textView7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dip" android:text="@string/blue"></TextView>
-            <SeekBar android:layout_height="wrap_content" android:max="255" android:id="@+id/led1Blue" android:layout_marginRight="16dip" android:layout_width="250dip"></SeekBar>
-            <SeekBar android:id="@+id/led2Blue" android:layout_height="wrap_content" android:max="255" android:layout_marginRight="16dip" android:layout_width="250dip"></SeekBar>
-            <SeekBar android:id="@+id/led3Blue" android:layout_height="wrap_content" android:max="255" android:layout_marginRight="16dip" android:layout_width="250dip"></SeekBar>
-        </TableRow>
-        <TableRow android:layout_height="wrap_content" android:id="@+id/tableRow2" android:layout_width="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:layout_marginBottom="8dip">
-            <TextView android:id="@+id/textView18" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/relays" android:layout_marginRight="8dip"></TextView>
-            <LinearLayout android:id="@+id/linearLayout2" android:layout_width="wrap_content" android:layout_height="wrap_content">
-                <TextView android:text="@string/relay1" android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dip"></TextView>
-                <ToggleButton android:text="ToggleButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/relay1Button"></ToggleButton>
-            </LinearLayout>
-            <LinearLayout android:id="@+id/linearLayout7" android:layout_width="wrap_content" android:layout_height="wrap_content">
-                <TextView android:layout_width="wrap_content" android:id="@+id/textView14" android:layout_height="wrap_content" android:text="@string/relay2" android:layout_marginRight="8dip"></TextView>
-                <ToggleButton android:layout_width="wrap_content" android:text="ToggleButton" android:layout_height="wrap_content" android:id="@+id/relay2Button"></ToggleButton>
-            </LinearLayout>
-        </TableRow>
-        <TableRow android:layout_height="wrap_content" android:id="@+id/tableRow3" android:layout_width="match_parent" android:layout_weight="1" android:layout_marginBottom="8dip">
-            <TextView android:text="@string/temperature" android:id="@+id/textView15" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dip"></TextView>
-            <TextView android:id="@+id/temperature" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
-        </TableRow>
-        <TableRow android:layout_height="wrap_content" android:id="@+id/tableRow13" android:layout_width="match_parent" android:layout_weight="1" android:layout_marginBottom="8dip">
-            <TextView android:text="@string/light" android:id="@+id/textView16" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dip"></TextView>
-            <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/light"></TextView>
-        </TableRow>
-        <TableRow android:id="@+id/tableRow7" android:layout_width="wrap_content" android:layout_height="wrap_content">
-            <TextView android:layout_marginRight="8dip" android:id="@+id/textView8" android:layout_width="wrap_content" android:text="@string/servos" android:layout_height="wrap_content"></TextView>
-            <SeekBar android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginRight="8dip" android:id="@+id/servo1" android:max="255" android:progress="127"></SeekBar>
-            <SeekBar android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginRight="8dip" android:id="@+id/servo2" android:max="255" android:progress="127"></SeekBar>
-            <SeekBar android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginRight="8dip" android:id="@+id/servo3" android:max="255" android:progress="127"></SeekBar>
-        </TableRow>
-        <TableRow android:layout_width="match_parent" android:id="@+id/tableRow8" android:layout_height="wrap_content">
-            <TextView android:id="@+id/textView9" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/joystick"></TextView>
-            <LinearLayout android:id="@+id/linearLayout3" android:layout_width="wrap_content" android:layout_height="wrap_content">
-                <TextView android:layout_width="wrap_content" android:id="@+id/textView10" android:layout_height="wrap_content" android:text="@string/x" android:layout_marginRight="8dip"></TextView>
-                <TextView android:layout_width="wrap_content" android:id="@+id/joyX" android:layout_height="wrap_content"></TextView>
-            </LinearLayout>
-            <LinearLayout android:id="@+id/linearLayout4" android:layout_width="wrap_content" android:layout_height="wrap_content">
-                <TextView android:layout_width="wrap_content" android:id="@+id/textView12" android:layout_height="wrap_content" android:text="@string/y" android:layout_marginRight="8dip"></TextView>
-                <TextView android:layout_width="wrap_content" android:id="@+id/joyY" android:layout_height="wrap_content"></TextView>
-            </LinearLayout>
-        </TableRow>
-        <TableRow android:layout_width="match_parent" android:id="@+id/tableRow9" android:layout_height="wrap_content">
-            <TextView android:id="@+id/textView11" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="@string/cap"></TextView>
-            <ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_gravity="left" android:src="@drawable/redball" android:id="@+id/cap"></ImageView>
-        </TableRow>
-    </TableLayout>
-
-</LinearLayout>
diff --git a/demokit/app/res/values/strings.xml b/demokit/app/res/values/strings.xml
deleted file mode 100644
index 54be6eb..0000000
--- a/demokit/app/res/values/strings.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="hello">Hello World, DemoKitActivity!</string>
-    <string name="app_name">DemoKit</string>
-    <string name="button1">1</string>
-    <string name="button2">2</string>
-    <string name="button3">3</string>
-    <string name="led1Red">Led 1 Red</string>
-    <string name="led1Green">Led 1 Green</string>
-    <string name="led1Blue">Led 1 Blue</string>
-    <string name="led2Red">Led 2 Red</string>
-    <string name="led2Green">Led 2 Green</string>
-    <string name="led2Blue">Led 2 Blue</string>
-    <string name="led3Red">Led 3 Red</string>
-    <string name="led3Green">Led 3 Green</string>
-    <string name="led3Blue">Led 3 Blue</string>
-    <string name="relay1">1</string>
-    <string name="relay2">2</string>
-    <string name="temperature">Temperature</string>
-    <string name="light">Light</string>
-    <string name="buttons">Buttons</string>
-    <string name="relays">Relays</string>
-    <string name="led1">Led 1</string>
-    <string name="led2">Led 2</string>
-    <string name="led3">Led 3</string>
-    <string name="red">Red</string>
-    <string name="green">Green</string>
-    <string name="blue">Blue</string>
-    <string name="servos">Servos</string>
-    <string name="x">X</string>
-    <string name="y">Y</string>
-    <string name="joystick">Joystick</string>
-    <string name="cap">Cap Button</string>
-</resources>
diff --git a/demokit/app/src/com/google/DemoKit/DemoKitActivity.java b/demokit/app/src/com/google/DemoKit/DemoKitActivity.java
deleted file mode 100644
index 338276f..0000000
--- a/demokit/app/src/com/google/DemoKit/DemoKitActivity.java
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.DemoKit;
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.SeekBar;
-import android.widget.ToggleButton;
-import android.widget.CompoundButton;
-import android.graphics.drawable.Drawable;
-
-import com.android.future.usb.UsbAccessory;
-import com.android.future.usb.UsbManager;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-
-public class DemoKitActivity extends Activity implements Runnable, SeekBar.OnSeekBarChangeListener, CompoundButton.OnCheckedChangeListener {
-    private static final String TAG = "DemoKit";
-
-    private static final String ACTION_USB_PERMISSION =
-            "com.google.DemoKit.action.USB_PERMISSION";
-
-    private UsbManager mUsbManager;
-    private PendingIntent mPermissionIntent;
-    private boolean mPermissionRequestPending;
-
-    UsbAccessory mAccessory;
-    ParcelFileDescriptor mFileDescriptor;
-    FileInputStream mInputStream;
-    FileOutputStream mOutputStream;
-
-    ImageView mButton1Image;
-    ImageView mButton2Image;
-    ImageView mButton3Image;
-
-    SeekBar mLed1Red;
-    SeekBar mLed1Green;
-    SeekBar mLed1Blue;
-    SeekBar mLed2Red;
-    SeekBar mLed2Green;
-    SeekBar mLed2Blue;
-    SeekBar mLed3Red;
-    SeekBar mLed3Green;
-    SeekBar mLed3Blue;
-
-    ToggleButton mRelay1Button;
-    ToggleButton mRelay2Button;
-
-    TextView mTemperature;
-    TextView mLight;
-
-    SeekBar mServo1;
-    SeekBar mServo2;
-    SeekBar mServo3;
-
-    TextView mJoyX;
-    TextView mJoyY;
-
-    ImageView mCap;
-
-
-    Drawable mSwitchOff;
-    Drawable mSwitchOn;
-
-    private static final int MESSAGE_SWITCH = 1;
-    private static final int MESSAGE_TEMPERATURE = 2;
-    private static final int MESSAGE_LIGHT = 3;
-    private static final int MESSAGE_JOY = 4;
-
-    private class SwitchMsg {
-        private byte sw;
-        private byte state;
-        public SwitchMsg(byte sw, byte state) {
-            this.sw = sw;
-            this.state = state;
-        }
-
-        public byte getSw() {
-            return sw;
-        }
-
-        public byte getState() {
-            return state;
-        }
-    }
-
-    private class TemperatureMsg {
-        private int temperature;
-
-        public TemperatureMsg(int temperature) {
-            this.temperature = temperature;
-        }
-
-        public int getTemperature() {
-            return temperature;
-        }
-    }
-
-    private class LightMsg {
-        private int light;
-
-        public LightMsg(int light) {
-            this.light = light;
-        }
-
-        public int getLight() {
-            return light;
-        }
-    }
-
-    private class JoyMsg {
-        private int x;
-        private int y;
-
-        public JoyMsg(int x, int y) {
-            this.x = x;
-            this.y = y;
-        }
-
-        public int getX() {
-            return x;
-        }
-
-        public int getY() {
-            return y;
-        }
-    }
-
-   private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (ACTION_USB_PERMISSION.equals(action)) {
-                synchronized (this) {
-                    UsbAccessory accessory = UsbManager.getAccessory(intent);
-                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
-                        openAccessory(accessory);
-                    } else {
-                        Log.d(TAG, "permission denied for accessory " + accessory);
-                    }
-                    mPermissionRequestPending = false;
-                }
-            } else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
-                UsbAccessory accessory = UsbManager.getAccessory(intent);
-                if (accessory != null && accessory.equals(mAccessory)) {
-                    closeAccessory();
-                }
-            }
-        }
-    };
-
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mUsbManager = UsbManager.getInstance(this);
-        mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
-        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
-        filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
-        registerReceiver(mUsbReceiver, filter);
-
-        setContentView(R.layout.main);
-
-        mButton1Image = (ImageView)findViewById(R.id.button1Image);
-        mButton2Image = (ImageView)findViewById(R.id.button2Image);
-        mButton3Image = (ImageView)findViewById(R.id.button3Image);
-
-        mLed1Red = (SeekBar)findViewById(R.id.led1Red);
-        mLed1Red.setOnSeekBarChangeListener(this);
-        mLed1Green = (SeekBar)findViewById(R.id.led1Green);
-        mLed1Green.setOnSeekBarChangeListener(this);
-        mLed1Blue = (SeekBar)findViewById(R.id.led1Blue);
-        mLed1Blue.setOnSeekBarChangeListener(this);
-
-        mLed2Red = (SeekBar)findViewById(R.id.led2Red);
-        mLed2Red.setOnSeekBarChangeListener(this);
-        mLed2Green = (SeekBar)findViewById(R.id.led2Green);
-        mLed2Green.setOnSeekBarChangeListener(this);
-        mLed2Blue = (SeekBar)findViewById(R.id.led2Blue);
-        mLed2Blue.setOnSeekBarChangeListener(this);
-
-        mLed3Red = (SeekBar)findViewById(R.id.led3Red);
-        mLed3Red.setOnSeekBarChangeListener(this);
-        mLed3Green = (SeekBar)findViewById(R.id.led3Green);
-        mLed3Green.setOnSeekBarChangeListener(this);
-        mLed3Blue = (SeekBar)findViewById(R.id.led3Blue);
-        mLed3Blue.setOnSeekBarChangeListener(this);
-
-        mRelay1Button = (ToggleButton)findViewById(R.id.relay1Button);
-        mRelay1Button.setOnCheckedChangeListener(this);
-        mRelay2Button = (ToggleButton)findViewById(R.id.relay2Button);
-        mRelay2Button.setOnCheckedChangeListener(this);
-
-        mTemperature = (TextView)findViewById(R.id.temperature);
-        mLight = (TextView)findViewById(R.id.light);
-
-        mServo1 = (SeekBar)findViewById(R.id.servo1);
-        mServo1.setOnSeekBarChangeListener(this);
-        mServo2 = (SeekBar)findViewById(R.id.servo2);
-        mServo2.setOnSeekBarChangeListener(this);
-        mServo3 = (SeekBar)findViewById(R.id.servo3);
-        mServo3.setOnSeekBarChangeListener(this);
-
-        mJoyX = (TextView)findViewById(R.id.joyX);
-        mJoyY = (TextView)findViewById(R.id.joyY);
-
-        mCap = (ImageView)findViewById(R.id.cap);
-
-        mSwitchOff = getResources().getDrawable(R.drawable.droid_off);
-        mSwitchOn = getResources().getDrawable(R.drawable.droid_on);
-
-        enableControls(false);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        Intent intent = getIntent();
-        Log.d(TAG, "intent: " + intent);
-        UsbAccessory[] accessories = mUsbManager.getAccessoryList();
-        UsbAccessory accessory = (accessories == null ? null : accessories[0]);
-        if (accessory != null) {
-            if (mUsbManager.hasPermission(accessory)) {
-                openAccessory(accessory);
-            } else {
-                synchronized (mUsbReceiver) {
-                    if (!mPermissionRequestPending) {
-                        mUsbManager.requestPermission(accessory, mPermissionIntent);
-                        mPermissionRequestPending = true;
-                    }
-                }
-            }
-        } else {
-            Log.d(TAG, "mAccessory is null");
-        }
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        closeAccessory();
-    }
-
-    @Override
-    public void onDestroy() {
-        unregisterReceiver(mUsbReceiver);
-       super.onDestroy();
-    }
-
-    private void openAccessory(UsbAccessory accessory) {
-        Log.d(TAG, "openAccessory: " + accessory);
-        mFileDescriptor = mUsbManager.openAccessory(accessory);
-        if (mFileDescriptor != null) {
-            mAccessory = accessory;
-            FileDescriptor fd = mFileDescriptor.getFileDescriptor();
-            mInputStream = new FileInputStream(fd);
-            mOutputStream = new FileOutputStream(fd);
-            Thread thread = new Thread(null, this, "AccessoryChat");
-            thread.start();
-            Log.d(TAG, "openAccessory succeeded");
-            enableControls(true);
-        } else {
-            Log.d(TAG, "openAccessory fail");
-        }
-    }
-
-    private void closeAccessory() {
-        enableControls(false);
-
-        mButton1Image.setImageDrawable(mSwitchOff);
-        mButton2Image.setImageDrawable(mSwitchOff);
-        mButton3Image.setImageDrawable(mSwitchOff);
-        mCap.setImageDrawable(mSwitchOff);
-        mLed1Red.setProgress(0);
-        mLed1Green.setProgress(0);
-        mLed1Blue.setProgress(0);
-        mLed2Red.setProgress(0);
-        mLed2Green.setProgress(0);
-        mLed2Blue.setProgress(0);
-        mLed3Red.setProgress(0);
-        mLed3Green.setProgress(0);
-        mLed3Blue.setProgress(0);
-        mServo1.setProgress(0);
-        mServo2.setProgress(0);
-        mServo3.setProgress(0);
-        mTemperature.setText("");
-        mLight.setText("");
-        mJoyX.setText("");
-        mJoyY.setText("");
-        mRelay1Button.setChecked(false);
-        mRelay2Button.setChecked(false);
-
-        try {
-            if (mFileDescriptor != null) {
-                mFileDescriptor.close();
-            }
-        } catch (IOException e) {
-        } finally {
-            mFileDescriptor = null;
-            mAccessory = null;
-        }
-    }
-
-    private void enableControls(boolean enable) {
-        mLed1Red.setEnabled(enable);
-        mLed1Green.setEnabled(enable);
-        mLed1Blue.setEnabled(enable);
-        mLed2Red.setEnabled(enable);
-        mLed2Green.setEnabled(enable);
-        mLed2Blue.setEnabled(enable);
-        mLed3Red.setEnabled(enable);
-        mLed3Green.setEnabled(enable);
-        mLed3Blue.setEnabled(enable);
-        mServo1.setEnabled(enable);
-        mServo2.setEnabled(enable);
-        mServo3.setEnabled(enable);
-        mRelay1Button.setEnabled(enable);
-        mRelay2Button.setEnabled(enable);
-    }
-
-    private int composeInt(byte hi, byte lo) {
-        int val = (int)hi & 0xff;
-        val *= 256;
-        val += (int)lo & 0xff;
-        return val;
-    }
-
-    public void run() {
-        int ret = 0;
-        byte[] buffer = new byte[16384];
-        int i;
-
-        while (ret >= 0) {
-            try {
-                ret = mInputStream.read(buffer);
-            } catch (IOException e) {
-                break;
-            }
-
-            Log.d(TAG, "got bytes " + ret);
-            i = 0;
-            while (i < ret) {
-                int len = ret - i;
-
-                switch (buffer[i]) {
-                case 0x1:
-                    if (len >= 3) {
-                        Message m = Message.obtain(mHandler, MESSAGE_SWITCH);
-                        m.obj = new SwitchMsg(buffer[i+1], buffer[i+2]);
-                        mHandler.sendMessage(m);
-                    }
-                    i += 3;
-                    break;
-
-                case 0x4:
-                    if (len >= 3) {
-                        Message m = Message.obtain(mHandler, MESSAGE_TEMPERATURE);
-                        m.obj = new TemperatureMsg(composeInt(buffer[i+1], buffer[i+2]));
-                        mHandler.sendMessage(m);
-                    }
-                    i += 3;
-                    break;
-
-                case 0x5:
-                    if (len >= 3) {
-                        Message m = Message.obtain(mHandler, MESSAGE_LIGHT);
-                        m.obj = new LightMsg(composeInt(buffer[i+1], buffer[i+2]));
-                        mHandler.sendMessage(m);
-                    }
-                    i += 3;
-                    break;
-
-                case 0x6:
-                    if (len >= 3) {
-                        Message m = Message.obtain(mHandler, MESSAGE_JOY);
-                        m.obj = new JoyMsg(buffer[i+1], buffer[i+2]);
-                        mHandler.sendMessage(m);
-                    }
-                    i += 3;
-                    break;
-
-                default:
-                    Log.d(TAG, "unknown msg: " + buffer[i]);
-                    i = len;
-                    break;
-                }
-            }
-
-        }
-        Log.d(TAG, "thread out");
-    }
-
-    Handler mHandler = new Handler() {
-            @Override
-            public void handleMessage(Message msg) {
-                switch (msg.what) {
-                case MESSAGE_SWITCH:
-                    SwitchMsg o = (SwitchMsg)msg.obj;
-                    if (o.getSw() == 0)
-                        mButton1Image.setImageDrawable(o.getState() != 0 ? mSwitchOn : mSwitchOff);
-                    else if (o.getSw() == 1)
-                        mButton2Image.setImageDrawable(o.getState() != 0 ? mSwitchOn : mSwitchOff);
-                    else if (o.getSw() == 2)
-                        mButton3Image.setImageDrawable(o.getState() != 0 ? mSwitchOn : mSwitchOff);
-                    else if (o.getSw() == 3)
-                        mCap.setImageDrawable(o.getState() != 0 ? mSwitchOn : mSwitchOff);
-                    break;
-
-                case MESSAGE_TEMPERATURE:
-                    TemperatureMsg t = (TemperatureMsg)msg.obj;
-                    mTemperature.setText(String.format("%04x", t.getTemperature()));
-                    break;
-
-                case MESSAGE_LIGHT:
-                    LightMsg l = (LightMsg)msg.obj;
-                    mLight.setText(String.format("%04x", l.getLight()));
-                    break;
-
-                case MESSAGE_JOY:
-                    JoyMsg j = (JoyMsg)msg.obj;
-                    mJoyX.setText(String.format("%d", j.getX()));
-                    mJoyY.setText(String.format("%d", j.getY()));
-                    break;
-
-                }
-            }
-        };
-
-    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-        byte[] buffer = new byte[3];
-        if (progress > 255)
-            progress = 255;
-
-        buffer[0] = 0x2;
-        buffer[1] = -1;
-        buffer[2] = (byte) progress;
-
-        if (seekBar == mLed1Red)
-            buffer[1] = 0x0;
-        else if (seekBar == mLed1Green)
-            buffer[1] = 0x1;
-        else if (seekBar == mLed1Blue)
-            buffer[1] = 0x2;
-        else if (seekBar == mLed2Red)
-            buffer[1] = 0x3;
-        else if (seekBar == mLed2Green)
-            buffer[1] = 0x4;
-        else if (seekBar == mLed2Blue)
-            buffer[1] = 0x5;
-        else if (seekBar == mLed3Red)
-            buffer[1] = 0x6;
-        else if (seekBar == mLed3Green)
-            buffer[1] = 0x7;
-        else if (seekBar == mLed3Blue)
-            buffer[1] = 0x8;
-        else if (seekBar == mServo1)
-            buffer[1] = 0x10;
-        else if (seekBar == mServo2)
-            buffer[1] = 0x11;
-        else if (seekBar == mServo3)
-            buffer[1] = 0x12;
-
-        if (buffer[1] != -1) {
-            try {
-                mOutputStream.write(buffer);
-            } catch (IOException e) {
-                Log.e(TAG, "write failed", e);
-            }
-        }
-
-    }
-
-    public void onStartTrackingTouch(SeekBar seekBar) {
-    }
-
-    public void onStopTrackingTouch(SeekBar seekBar) {
-    }
-
-    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-        byte[] buffer = new byte[3];
-        buffer[0] = 0x3;
-        buffer[1] = -1;
-        buffer[2] = isChecked ? (byte)0x1 : (byte)0x0;
-
-        if (buttonView == mRelay1Button)
-            buffer[1] = 0;
-        else if (buttonView == mRelay2Button)
-            buffer[1] = 1;
-
-        if (buffer[1] != -1) {
-            try {
-                mOutputStream.write(buffer);
-            } catch (IOException e) {
-                Log.e(TAG, "write failed", e);
-            }
-        }
-    }
-}
-
diff --git a/demokit/demokit.pde b/demokit/demokit.pde
deleted file mode 100644
index 5a4d29a..0000000
--- a/demokit/demokit.pde
+++ /dev/null
@@ -1,405 +0,0 @@
-#include <Wire.h>
-#include <Servo.h>
-
-#include <Max3421e.h>
-#include <Usb.h>
-#include <AndroidAccessory.h>
-
-#define  LED3_RED       2
-#define  LED3_GREEN     4
-#define  LED3_BLUE      3
-
-#define  LED2_RED       5
-#define  LED2_GREEN     7
-#define  LED2_BLUE      6
-
-#define  LED1_RED       8
-#define  LED1_GREEN     10
-#define  LED1_BLUE      9
-
-#define  SERVO1         11
-#define  SERVO2         12
-#define  SERVO3         13
-
-#define  TOUCH          14
-
-#define  RELAY1         A0
-#define  RELAY2         A1
-
-#define  LIGHT_SENSOR   A2
-#define  TEMP_SENSOR    A3
-
-#define  BUTTON1        A6
-#define  BUTTON2        A7
-#define  BUTTON3        A8
-
-#define  JOY_SWITCH     A9      // pulls line down when pressed
-#define  JOY_nINT       A10     // active low interrupt input
-#define  JOY_nRESET     A11     // active low reset output
-
-AndroidAccessory acc("Google, Inc.",
-		     "DemoKit",
-		     "DemoKit Arduino Board",
-		     "1.0",
-		     "http://www.android.com",
-		     "0000000012345678");
-Servo servos[3];
-
-void setup();
-void loop();
-
-void init_buttons()
-{
-	pinMode( BUTTON1, INPUT );
-	pinMode( BUTTON2, INPUT );
-	pinMode( BUTTON3, INPUT );
-
-	digitalWrite( BUTTON1, HIGH );  // enable the internal pullups
-	digitalWrite( BUTTON2, HIGH );
-	digitalWrite( BUTTON3, HIGH );
-}
-
-
-void init_relays()
-{
-	pinMode( RELAY1, OUTPUT );
-	pinMode( RELAY2, OUTPUT );
-}
-
-
-void init_leds()
-{
-	digitalWrite( LED1_RED,   1 );
-	digitalWrite( LED1_GREEN, 1 );
-	digitalWrite( LED1_BLUE,  1 );
-
-	pinMode( LED1_RED,    OUTPUT );
-	pinMode( LED1_GREEN,  OUTPUT );
-	pinMode( LED1_BLUE,   OUTPUT );
-
-	digitalWrite( LED2_RED,   1 );
-	digitalWrite( LED2_GREEN, 1 );
-	digitalWrite( LED2_BLUE,  1 );
-
-	pinMode( LED2_RED,    OUTPUT );
-	pinMode( LED2_GREEN,  OUTPUT );
-	pinMode( LED2_BLUE,   OUTPUT );
-
-	digitalWrite( LED3_RED,   1 );
-	digitalWrite( LED3_GREEN, 1 );
-	digitalWrite( LED3_BLUE,  1 );
-
-	pinMode( LED3_RED,    OUTPUT );
-	pinMode( LED3_GREEN,  OUTPUT );
-	pinMode( LED3_BLUE,   OUTPUT );
-}
-
-void init_joystick( int threshold );
-
-byte b1, b2, b3, c;
-void setup()
-{
-	Serial.begin( 115200 );
-	Serial.print("\r\nStart");
-
-	init_leds();
-	init_relays();
-	init_buttons();
-	init_joystick( 5 );      // initialize with thresholding enabled, dead zone of 5 units  
-
-
-	servos[0].attach(SERVO1);
-	servos[0].write(90);
-	servos[1].attach(SERVO2);
-	servos[1].write(90);
-	servos[2].attach(SERVO3);
-	servos[2].write(90);
-
-
-	b1 = digitalRead(BUTTON1);
-	b2 = digitalRead(BUTTON2);
-	b3 = digitalRead(BUTTON3);
-	c = captouched();
-
-	acc.powerOn();
-}
-
-void loop()
-{
-	byte err;
-	byte idle;
-	static byte count = 0;
-	byte msg[3];
-
-	if (acc.isConnected()) {
-		int len = acc.read(msg, sizeof(msg), 1);
-		int i;
-		byte b;
-		uint16_t val;
-		int x, y;
-		char c0;
-
-		if (len > 0) {
-			// XXX: assumes only one command per packet
-			Serial.print(msg[0], HEX);
-			Serial.print(":");
-			Serial.print(msg[1], HEX);
-			Serial.print(":");
-			Serial.println(msg[2], HEX);
-			if (msg[0] == 0x2) {
-				if (msg[1] == 0x0)
-					analogWrite( LED1_RED, 255 - msg[2]);
-				else if (msg[1] == 0x1)
-					analogWrite( LED1_GREEN, 255 - msg[2]);
-				else if (msg[1] == 0x2)
-					analogWrite( LED1_BLUE, 255 - msg[2]);
-				else if (msg[1] == 0x3)
-					analogWrite( LED2_RED, 255 - msg[2]);
-				else if (msg[1] == 0x4)
-					analogWrite( LED2_GREEN, 255 - msg[2]);
-				else if (msg[1] == 0x5)
-					analogWrite( LED2_BLUE, 255 - msg[2]);
-				else if (msg[1] == 0x6)
-					analogWrite( LED3_RED, 255 - msg[2]);
-				else if (msg[1] == 0x7)
-					analogWrite( LED3_GREEN, 255 - msg[2]);
-				else if (msg[1] == 0x8)
-					analogWrite( LED3_BLUE, 255 - msg[2]);
-				else if (msg[1] == 0x10)
-					servos[0].write(map(msg[2], 0, 255, 0, 180));
-				else if (msg[1] == 0x11)
-					servos[1].write(map(msg[2], 0, 255, 0, 180));
-				else if (msg[1] == 0x12)
-					servos[2].write(map(msg[2], 0, 255, 0, 180));
-			} else if (msg[0] == 0x3) {
-				if (msg[1] == 0x0)
-					digitalWrite( RELAY1, msg[2] ? HIGH : LOW );
-				else if (msg[1] == 0x1)
-					digitalWrite( RELAY2, msg[2] ? HIGH : LOW );
-
-			}
-
-		}
-
-		msg[0] = 0x1;
-
-		b = digitalRead(BUTTON1);
-		if (b != b1) {
-			msg[1] = 0;
-			msg[2] = b ? 0 : 1;
-			acc.write(msg, 3);
-			b1 = b;
-		}
-
-		b = digitalRead(BUTTON2);
-		if (b != b2) {
-			msg[1] = 1;
-			msg[2] = b ? 0 : 1;
-			acc.write(msg, 3);
-			b2 = b;
-		}
-
-		b = digitalRead(BUTTON3);
-		if (b != b3) {
-			msg[1] = 2;
-			msg[2] = b ? 0 : 1;
-			acc.write(msg, 3);
-			b3 = b;
-		}
-
-		switch (count++ % 0x10) {
-
-		case 0:
-			val = analogRead(TEMP_SENSOR);
-			msg[0] = 0x4;
-			msg[1] = val >> 8;
-			msg[2] = val & 0xff;
-			acc.write(msg, 3);
-			break;
-
-		case 0x4:
-			val = analogRead(LIGHT_SENSOR);
-			msg[0] = 0x5;
-			msg[1] = val >> 8;
-			msg[2] = val & 0xff;
-			acc.write(msg, 3);
-			break;
-
-		case 0x8:
-			read_joystick(&x, &y);
-			msg[0] = 0x6;
-			msg[1] = constrain(x, -128, 127);
-			msg[2] = constrain(y, -128, 127);
-			acc.write(msg, 3);
-			break;
-
-#if 0
-			/* captoutched needs to be asynchonous */
-		case 0xc:
-			c0 = captouched();
-			if (c0 != c) {
-				msg[0] = 0x1;
-				msg[1] = 3;
-				msg[2] = c0 ? 0 : 1;
-				acc.write(msg, 3);
-				c = c0;
-			}
-			break;
-#endif
-		}
-	}
-
-	delay(10);
-}
-
-// ==============================================================================
-// Austria Microsystems i2c Joystick
-
-/*
-  If a threshold is provided, the dead zone will be programmed such that interrupts will not
-  be generated unless the threshold is exceeded.
-
-  Note that if you use that mode, you will have to use passage of time with no new interrupts
-  to detect that the stick has been released and has returned to center.
-  
-  If you need to explicitly track return to center, pass 0 as the threshold.  "Center" will
-  still bounce around a little 
-*/
-
-
-void init_joystick( int threshold )
-{
-  byte status = 0;
-  
-  pinMode( JOY_SWITCH, INPUT );
-  digitalWrite( JOY_SWITCH, HIGH );    // enable the internal pullup
-  
-  pinMode( JOY_nINT, INPUT );
-  digitalWrite( JOY_nINT, HIGH );      // enable the internal pullup
-
-  pinMode( JOY_nRESET, OUTPUT );
-
-  digitalWrite( JOY_nRESET, 1 );
-  delay(1);
-  digitalWrite( JOY_nRESET, 0 );
-  delay(1);
-  digitalWrite( JOY_nRESET, 1 );
-
-  Wire.begin();
-  
-  do {
-    status = read_joy_reg( 0x0f );        // XXX need timeout
-  } while ((status & 0xf0) != 0xf0);
-  
-  write_joy_reg( 0x2e, 0x86 );            // invert magnet polarity setting, per datasheet
-
-  calibrate_joystick( threshold );        // calibrate & set up dead zone area  
-}
-
-
-int offset_X, offset_Y;
-
-void calibrate_joystick( int dz )
-{
-  char iii;
-  int x_cal = 0;
-  int y_cal = 0;
-
-  write_joy_reg( 0x0f, 0x00 );          // Low Power Mode, 20ms auto wakeup
-                                        // INTn output enabled
-                                        // INTn active after each measurement
-                                        // Normal (non-Reset) mode
-  delay(1);
-
-  read_joy_reg( 0x11 );                 // dummy read of Y_reg to reset interrupt
-
-  for( iii = 0; iii != 16; iii++ ) {    // read coords 16 times & average 
-    while( !joystick_interrupt() )      // poll for interrupt
-      ;
-    x_cal += read_joy_reg( 0x10 );      // X pos
-    y_cal += read_joy_reg( 0x11 );      // Y pos
-  }
-  
-  offset_X = -(x_cal>>4);               // divide by 16 to get average
-  offset_Y = -(y_cal>>4);
-  
-  //sprintf(msgbuf, "offsets = %d, %d\n", offset_X, offset_Y);
-  //Serial.print(msgbuf);
-  
-  write_joy_reg( 0x12,  dz - offset_X );  // Xp, LEFT threshold for INTn
-  write_joy_reg( 0x13, -dz - offset_X );  // Xn, RIGHT threshold for INTn
-  write_joy_reg( 0x14,  dz - offset_Y );  // Yp, UP threshold for INTn
-  write_joy_reg( 0x15, -dz - offset_Y );  // Yn, DOWN threshold for INTn
-
-  if ( dz )                             // dead zone threshold detect requested?
-    write_joy_reg( 0x0f, 0x04 );          // Low Power Mode, 20ms auto wakeup
-                                          // INTn output enabled
-                                          // INTn active when movement exceeds dead zone
-                                          // Normal (non-Reset) mode
-}
-
-
-void read_joystick( int *x, int *y )
-{
-  *x = read_joy_reg( 0x10 ) + offset_X;
-  *y = read_joy_reg( 0x11 ) + offset_Y;  // reading Y clears the interrupt
-}
-
-char joystick_interrupt()
-{
-  return ( digitalRead( JOY_nINT ) == 0 ); 
-}
-
-
-#define  JOY_I2C_ADDR    0x40
-
-char read_joy_reg( char reg_addr )
-{
-  char c;
-  
-  Wire.beginTransmission( JOY_I2C_ADDR );
-  Wire.send( reg_addr );
-  Wire.endTransmission();
-  
-  Wire.requestFrom( JOY_I2C_ADDR, 1 );
-  
-  while(Wire.available())
-    c = Wire.receive();
-  
-  return c;
-}
-
-void write_joy_reg( char reg_addr, char val )
-{
-  Wire.beginTransmission( JOY_I2C_ADDR );
-  Wire.send( reg_addr );
-  Wire.send( val );
-  Wire.endTransmission();  
-}
-
-/* Capacitive touch technique from Mario Becker, Fraunhofer IGD, 2007 http://www.igd.fhg.de/igd-a4 */
-
-char captouched() 
-{
-  char iii, jjj, retval;
-  
-  retval = 0;
-  
-  for( jjj = 0; jjj != 10; jjj++ ) {
-    delay( 10 );
-  
-    pinMode( TOUCH, INPUT );
-    digitalWrite( TOUCH, HIGH );
-  
-    for ( iii = 0; iii <  16; iii++ )
-      if( digitalRead( TOUCH ) )
-        break;
-      
-    digitalWrite( TOUCH, LOW );
-    pinMode( TOUCH, OUTPUT );
-  
-    retval += iii;
-  }
-  
-  return retval;
-}
diff --git a/firmware/demokit/demokit.pde b/firmware/demokit/demokit.pde
new file mode 100644
index 0000000..feb112f
--- /dev/null
+++ b/firmware/demokit/demokit.pde
@@ -0,0 +1,394 @@
+#include <Wire.h>
+#include <Servo.h>
+
+#include <Max3421e.h>
+#include <Usb.h>
+#include <AndroidAccessory.h>
+
+#include <CapSense.h>
+
+#define  LED3_RED       2
+#define  LED3_GREEN     4
+#define  LED3_BLUE      3
+
+#define  LED2_RED       5
+#define  LED2_GREEN     7
+#define  LED2_BLUE      6
+
+#define  LED1_RED       8
+#define  LED1_GREEN     10
+#define  LED1_BLUE      9
+
+#define  SERVO1         11
+#define  SERVO2         12
+#define  SERVO3         13
+
+#define  TOUCH_RECV     14
+#define  TOUCH_SEND     15
+
+#define  RELAY1         A0
+#define  RELAY2         A1
+
+#define  LIGHT_SENSOR   A2
+#define  TEMP_SENSOR    A3
+
+#define  BUTTON1        A6
+#define  BUTTON2        A7
+#define  BUTTON3        A8
+
+#define  JOY_SWITCH     A9      // pulls line down when pressed
+#define  JOY_nINT       A10     // active low interrupt input
+#define  JOY_nRESET     A11     // active low reset output
+
+AndroidAccessory acc("Google, Inc.",
+		     "DemoKit",
+		     "DemoKit Arduino Board",
+		     "1.0",
+		     "http://www.android.com",
+		     "0000000012345678");
+Servo servos[3];
+
+// 10M ohm resistor on demo shield
+CapSense   touch_robot = CapSense(TOUCH_SEND, TOUCH_RECV);
+
+void setup();
+void loop();
+
+void init_buttons()
+{
+	pinMode(BUTTON1, INPUT);
+	pinMode(BUTTON2, INPUT);
+	pinMode(BUTTON3, INPUT);
+	pinMode(JOY_SWITCH, INPUT);
+
+	// enable the internal pullups
+	digitalWrite(BUTTON1, HIGH);
+	digitalWrite(BUTTON2, HIGH);
+	digitalWrite(BUTTON3, HIGH);
+	digitalWrite(JOY_SWITCH, HIGH);
+}
+
+
+void init_relays()
+{
+	pinMode(RELAY1, OUTPUT);
+	pinMode(RELAY2, OUTPUT);
+}
+
+
+void init_leds()
+{
+	digitalWrite(LED1_RED, 1);
+	digitalWrite(LED1_GREEN, 1);
+	digitalWrite(LED1_BLUE, 1);
+
+	pinMode(LED1_RED, OUTPUT);
+	pinMode(LED1_GREEN, OUTPUT);
+	pinMode(LED1_BLUE, OUTPUT);
+
+	digitalWrite(LED2_RED, 1);
+	digitalWrite(LED2_GREEN, 1);
+	digitalWrite(LED2_BLUE, 1);
+
+	pinMode(LED2_RED, OUTPUT);
+	pinMode(LED2_GREEN, OUTPUT);
+	pinMode(LED2_BLUE, OUTPUT);
+
+	digitalWrite(LED3_RED, 1);
+	digitalWrite(LED3_GREEN, 1);
+	digitalWrite(LED3_BLUE, 1);
+
+	pinMode(LED3_RED, OUTPUT);
+	pinMode(LED3_GREEN, OUTPUT);
+	pinMode(LED3_BLUE, OUTPUT);
+}
+
+void init_joystick(int threshold);
+
+byte b1, b2, b3, b4, c;
+void setup()
+{
+	Serial.begin(115200);
+	Serial.print("\r\nStart");
+
+	init_leds();
+	init_relays();
+	init_buttons();
+	init_joystick( 5 );
+
+	// autocalibrate OFF
+	touch_robot.set_CS_AutocaL_Millis(0xFFFFFFFF);
+
+	servos[0].attach(SERVO1);
+	servos[0].write(90);
+	servos[1].attach(SERVO2);
+	servos[1].write(90);
+	servos[2].attach(SERVO3);
+	servos[2].write(90);
+
+
+	b1 = digitalRead(BUTTON1);
+	b2 = digitalRead(BUTTON2);
+	b3 = digitalRead(BUTTON3);
+	b4 = digitalRead(JOY_SWITCH);
+	c = 0;
+
+	acc.powerOn();
+}
+
+void loop()
+{
+	byte err;
+	byte idle;
+	static byte count = 0;
+	byte msg[3];
+	long touchcount;
+
+	if (acc.isConnected()) {
+		int len = acc.read(msg, sizeof(msg), 1);
+		int i;
+		byte b;
+		uint16_t val;
+		int x, y;
+		char c0;
+
+		if (len > 0) {
+			// assumes only one command per packet
+			if (msg[0] == 0x2) {
+				if (msg[1] == 0x0)
+					analogWrite(LED1_RED, 255 - msg[2]);
+				else if (msg[1] == 0x1)
+					analogWrite(LED1_GREEN, 255 - msg[2]);
+				else if (msg[1] == 0x2)
+					analogWrite(LED1_BLUE, 255 - msg[2]);
+				else if (msg[1] == 0x3)
+					analogWrite(LED2_RED, 255 - msg[2]);
+				else if (msg[1] == 0x4)
+					analogWrite(LED2_GREEN, 255 - msg[2]);
+				else if (msg[1] == 0x5)
+					analogWrite(LED2_BLUE, 255 - msg[2]);
+				else if (msg[1] == 0x6)
+					analogWrite(LED3_RED, 255 - msg[2]);
+				else if (msg[1] == 0x7)
+					analogWrite(LED3_GREEN, 255 - msg[2]);
+				else if (msg[1] == 0x8)
+					analogWrite(LED3_BLUE, 255 - msg[2]);
+				else if (msg[1] == 0x10)
+					servos[0].write(map(msg[2], 0, 255, 0, 180));
+				else if (msg[1] == 0x11)
+					servos[1].write(map(msg[2], 0, 255, 0, 180));
+				else if (msg[1] == 0x12)
+					servos[2].write(map(msg[2], 0, 255, 0, 180));
+			} else if (msg[0] == 0x3) {
+				if (msg[1] == 0x0)
+					digitalWrite(RELAY1, msg[2] ? HIGH : LOW);
+				else if (msg[1] == 0x1)
+					digitalWrite(RELAY2, msg[2] ? HIGH : LOW);
+			}
+		}
+
+		msg[0] = 0x1;
+
+		b = digitalRead(BUTTON1);
+		if (b != b1) {
+			msg[1] = 0;
+			msg[2] = b ? 0 : 1;
+			acc.write(msg, 3);
+			b1 = b;
+		}
+
+		b = digitalRead(BUTTON2);
+		if (b != b2) {
+			msg[1] = 1;
+			msg[2] = b ? 0 : 1;
+			acc.write(msg, 3);
+			b2 = b;
+		}
+
+		b = digitalRead(BUTTON3);
+		if (b != b3) {
+			msg[1] = 2;
+			msg[2] = b ? 0 : 1;
+			acc.write(msg, 3);
+			b3 = b;
+		}
+
+		b = digitalRead(JOY_SWITCH);
+		if (b != b4) {
+			msg[1] = 4;
+			msg[2] = b ? 0 : 1;
+			acc.write(msg, 3);
+			b4 = b;
+		}
+
+		switch (count++ % 0x10) {
+		case 0:
+			val = analogRead(TEMP_SENSOR);
+			msg[0] = 0x4;
+			msg[1] = val >> 8;
+			msg[2] = val & 0xff;
+			acc.write(msg, 3);
+			break;
+
+		case 0x4:
+			val = analogRead(LIGHT_SENSOR);
+			msg[0] = 0x5;
+			msg[1] = val >> 8;
+			msg[2] = val & 0xff;
+			acc.write(msg, 3);
+			break;
+
+		case 0x8:
+			read_joystick(&x, &y);
+			msg[0] = 0x6;
+			msg[1] = constrain(x, -128, 127);
+			msg[2] = constrain(y, -128, 127);
+			acc.write(msg, 3);
+			break;
+
+		case 0xc:
+			touchcount = touch_robot.capSense(5);
+
+			c0 = touchcount > 750;
+
+			if (c0 != c) {
+				msg[0] = 0x1;
+				msg[1] = 3;
+				msg[2] = c0;
+				acc.write(msg, 3);
+				c = c0;
+			}
+
+			break;
+		}
+	} else {
+		// reset outputs to default values on disconnect
+		analogWrite(LED1_RED, 255);
+		analogWrite(LED1_GREEN, 255);
+		analogWrite(LED1_BLUE, 255);
+		analogWrite(LED2_RED, 255);
+		analogWrite(LED2_GREEN, 255);
+		analogWrite(LED2_BLUE, 255);
+		analogWrite(LED3_RED, 255);
+		analogWrite(LED3_GREEN, 255);
+		analogWrite(LED3_BLUE, 255);
+		servos[0].write(90);
+		servos[0].write(90);
+		servos[0].write(90);
+		digitalWrite(RELAY1, LOW);
+		digitalWrite(RELAY2, LOW);
+	}
+
+	delay(10);
+}
+
+// ==============================================================================
+// Austria Microsystems i2c Joystick
+void init_joystick(int threshold)
+{
+	byte status = 0;
+
+	pinMode(JOY_SWITCH, INPUT);
+	digitalWrite(JOY_SWITCH, HIGH);
+
+	pinMode(JOY_nINT, INPUT);
+	digitalWrite(JOY_nINT, HIGH);
+
+	pinMode(JOY_nRESET, OUTPUT);
+
+	digitalWrite(JOY_nRESET, 1);
+	delay(1);
+	digitalWrite(JOY_nRESET, 0);
+	delay(1);
+	digitalWrite(JOY_nRESET, 1);
+
+	Wire.begin();
+
+	do {
+		status = read_joy_reg(0x0f);
+	} while ((status & 0xf0) != 0xf0);
+
+	// invert magnet polarity setting, per datasheet
+	write_joy_reg(0x2e, 0x86);
+
+	calibrate_joystick(threshold);
+}
+
+
+int offset_X, offset_Y;
+
+void calibrate_joystick(int dz)
+{
+	char iii;
+	int x_cal = 0;
+	int y_cal = 0;
+
+	// Low Power Mode, 20ms auto wakeup
+	// INTn output enabled
+	// INTn active after each measurement
+	// Normal (non-Reset) mode
+	write_joy_reg(0x0f, 0x00);
+	delay(1);
+
+	// dummy read of Y_reg to reset interrupt
+	read_joy_reg(0x11);
+
+	for(iii = 0; iii != 16; iii++) {
+		while(!joystick_interrupt()) {}
+
+		x_cal += read_joy_reg(0x10);
+		y_cal += read_joy_reg(0x11);
+	}
+
+	// divide by 16 to get average
+	offset_X = -(x_cal>>4);
+	offset_Y = -(y_cal>>4);
+
+	write_joy_reg(0x12, dz - offset_X);  // Xp, LEFT threshold for INTn
+	write_joy_reg(0x13, -dz - offset_X);  // Xn, RIGHT threshold for INTn
+	write_joy_reg(0x14, dz - offset_Y);  // Yp, UP threshold for INTn
+	write_joy_reg(0x15, -dz - offset_Y);  // Yn, DOWN threshold for INTn
+
+	// dead zone threshold detect requested?
+	if (dz)
+		write_joy_reg(0x0f, 0x04);
+}
+
+
+void read_joystick(int *x, int *y)
+{
+	*x = read_joy_reg(0x10) + offset_X;
+	*y = read_joy_reg(0x11) + offset_Y;  // reading Y clears the interrupt
+}
+
+char joystick_interrupt()
+{
+	return digitalRead(JOY_nINT) == 0;
+}
+
+
+#define  JOY_I2C_ADDR    0x40
+
+char read_joy_reg(char reg_addr)
+{
+	char c;
+
+	Wire.beginTransmission(JOY_I2C_ADDR);
+	Wire.send(reg_addr);
+	Wire.endTransmission();
+
+	Wire.requestFrom(JOY_I2C_ADDR, 1);
+
+	while(Wire.available())
+		c = Wire.receive();
+
+	return c;
+}
+
+void write_joy_reg(char reg_addr, char val)
+{
+	Wire.beginTransmission(JOY_I2C_ADDR);
+	Wire.send(reg_addr);
+	Wire.send(val);
+	Wire.endTransmission();
+}
diff --git a/labyrinth/labyrinth.pde b/labyrinth/labyrinth.pde
deleted file mode 100644
index a5e759a..0000000
--- a/labyrinth/labyrinth.pde
+++ /dev/null
@@ -1,519 +0,0 @@
-#include <Max3421e.h>
-#include <Usb.h>
-#include <Wire.h>
-#include <Servo.h>
-
-#define USB_ACCESSORY_VENDOR_ID 0x18D1
-#define USB_ACCESSORY_PRODUCT_ID 0x2D00
-
-#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
-#define ACCESSORY_STRING_MANUFACTURER 0
-#define ACCESSORY_STRING_MODEL 1
-#define ACCESSORY_STRING_TYPE 2
-#define ACCESSORY_STRING_VERSION 3
-
-#define ACCESSORY_SEND_STRING 52
-#define ACCESSORY_START 53
-
-
-#define  LED3_RED       2
-#define  LED3_GREEN     3
-#define  LED3_BLUE      4
-
-#define  LED2_RED       5
-#define  LED2_GREEN     6
-#define  LED2_BLUE      7
-
-#define  LED1_RED       8
-#define  LED1_GREEN     9
-#define  LED1_BLUE      10
-
-#define  SERVO1         11
-#define  SERVO2         12
-#define  SERVO3         13
-
-#define  TOUCH          14
-
-#define  RELAY1         A0
-#define  RELAY2         A1
-
-#define  LIGHT_SENSOR   A2
-#define  TEMP_SENSOR    A3
-
-#define  BUTTON1        A6
-#define  BUTTON2        A7
-#define  BUTTON3        A8
-
-#define  JOY_SWITCH     A9      // pulls line down when pressed
-#define  JOY_nINT       A10     // active low interrupt input
-#define  JOY_nRESET     A11     // active low reset output
-
-
-MAX3421E Max;
-USB Usb;
-Servo servos[3];
-
-
-void setup();
-void loop();
-
-uint8_t usbBuff[256];
-
-
-void init_buttons()
-{
-	pinMode( BUTTON1, INPUT );
-	pinMode( BUTTON2, INPUT );
-	pinMode( BUTTON3, INPUT );
-
-	digitalWrite( BUTTON1, HIGH );  // enable the internal pullups
-	digitalWrite( BUTTON2, HIGH );
-	digitalWrite( BUTTON3, HIGH );
-}
-
-
-void init_relays()
-{
-	pinMode( RELAY1, OUTPUT );
-	pinMode( RELAY2, OUTPUT );
-}
-
-
-void init_leds()
-{
-	digitalWrite( LED1_RED,   1 );
-	digitalWrite( LED1_GREEN, 1 );
-	digitalWrite( LED1_BLUE,  1 );
-
-	pinMode( LED1_RED,    OUTPUT );
-	pinMode( LED1_GREEN,  OUTPUT );
-	pinMode( LED1_BLUE,   OUTPUT );
-
-	digitalWrite( LED2_RED,   1 );
-	digitalWrite( LED2_GREEN, 1 );
-	digitalWrite( LED2_BLUE,  1 );
-
-	pinMode( LED2_RED,    OUTPUT );
-	pinMode( LED2_GREEN,  OUTPUT );
-	pinMode( LED2_BLUE,   OUTPUT );
-
-	digitalWrite( LED3_RED,   1 );
-	digitalWrite( LED3_GREEN, 1 );
-	digitalWrite( LED3_BLUE,  1 );
-
-	pinMode( LED3_RED,    OUTPUT );
-	pinMode( LED3_GREEN,  OUTPUT );
-	pinMode( LED3_BLUE,   OUTPUT );
-}
-
-void init_joystick( int threshold );
-
-void setup()
-{
-	Serial.begin( 115200 );
-	Serial.print("\r\nStart");
-
-	init_leds();
-	init_relays();
-	init_buttons();
-	init_joystick( 5 );      // initialize with thresholding enabled, dead zone of 5 units  
-
-
-	servos[0].attach(SERVO1);
-	servos[0].write(90);
-	servos[1].attach(SERVO2);
-	servos[1].write(90);
-	servos[2].attach(SERVO3);
-	servos[2].write(90);
-
-	Max.powerOn();
-	delay( 200 );
-}
-
-bool isAndroidVendor(USB_DEVICE_DESCRIPTOR *desc)
-{
-	return desc->idVendor == 0x18d1 || desc->idVendor == 0x22B8;
-}
-
-bool isAccessoryDevice(USB_DEVICE_DESCRIPTOR *desc)
-{
-	return desc->idProduct == 0x2D00 || desc->idProduct == 0x2D01;
-}
-
-void sendString(byte addr, int index, char *str)
-{
-	Usb.ctrlReq(addr, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE,
-		    ACCESSORY_SEND_STRING, 0, 0, index, strlen(str) + 1, str);
-
-}
-
-void switchDevice(byte addr)
-{
-	sendString(addr, ACCESSORY_STRING_MANUFACTURER, "Google, Inc.");
-	sendString(addr, ACCESSORY_STRING_MODEL, "DemoKit");
-	sendString(addr, ACCESSORY_STRING_TYPE, "Sample Program");
-	sendString(addr, ACCESSORY_STRING_VERSION, "1.0");
-
-	Usb.ctrlReq(addr, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE,
-		    ACCESSORY_START, 0, 0, 0, 0, NULL);
-}
-
-bool findEndpoints(byte addr, EP_RECORD *inEp, EP_RECORD *outEp)
-{
-	int len;
-	byte err;
-	uint8_t *p;
-
-	err = Usb.getConfDescr(addr, 0, 4, 0, (char *)usbBuff);
-	if (err) {
-		Serial.print("Can't get config descriptor length\n");
-		return false;
-	}
-
-	len = usbBuff[2] | ((int)usbBuff[3] << 8);
-	Serial.print("Config Desc Length: ");
-	Serial.println(len, DEC);
-	if (len > sizeof(usbBuff)) {
-		Serial.print("config descriptor too large\n");
-		/* might want to truncate here */
-		return false;
-	}
-
-	err = Usb.getConfDescr(addr, 0, len, 0, (char *)usbBuff);
-	if (err) {
-		Serial.print("Can't get config descriptor\n");
-		return false;
-	}
-
-	p = usbBuff;
-	inEp->epAddr = 0;
-	outEp->epAddr = 0;
-	while (p < (usbBuff + len)){
-		uint8_t descLen = p[0];
-		uint8_t descType = p[1];
-		USB_ENDPOINT_DESCRIPTOR *epDesc;
-		EP_RECORD *ep;
-
-		switch (descType) {
-		case USB_DESCRIPTOR_CONFIGURATION:
-			Serial.print("config desc\n");
-			break;
-
-		case USB_DESCRIPTOR_INTERFACE:
-			Serial.print("interface desc\n");
-			break;
-
-		case USB_DESCRIPTOR_ENDPOINT:
-			epDesc = (USB_ENDPOINT_DESCRIPTOR *)p;
-			if (!inEp->epAddr && (epDesc->bEndpointAddress & 0x80))
-				ep = inEp;
-			else if (!outEp->epAddr)
-				ep = outEp;
-			else
-				ep = NULL;
-
-			if (ep) {
-				ep->epAddr = epDesc->bEndpointAddress & 0x7f;
-				ep->Attr = epDesc->bmAttributes;
-				ep->MaxPktSize = epDesc->wMaxPacketSize;
-				ep->sndToggle = bmSNDTOG0;
-				ep->rcvToggle = bmRCVTOG0;
-			}
-			break;
-
-		default:
-			Serial.print("unkown desc type ");
-			Serial.println( descType, HEX);
-			break;
-		}
-
-		p += descLen;
-	}
-
-	return inEp->epAddr && outEp->epAddr;
-}
-
-EP_RECORD ep_record[ 8 ];  //endpoint record structure for the mouse
-
-
-void doAndroid(void)
-{
-	byte err;
-	byte idle;
-	byte b1, b2, b3, c;
-	EP_RECORD inEp, outEp;
-	byte count = 0;
-
-	if (findEndpoints(1, &inEp, &outEp)) {
-
-		ep_record[inEp.epAddr] = inEp;
-		if (outEp.epAddr != inEp.epAddr)
-			ep_record[outEp.epAddr] = outEp;
-
-		Serial.print("inEp: ");
-		Serial.println(inEp.epAddr, HEX);
-		Serial.print("outEp: ");
-		Serial.println(outEp.epAddr, HEX);
-
-		ep_record[0] = *(Usb.getDevTableEntry(0,0));
-		Usb.setDevTableEntry(1, ep_record);
-
-		err = Usb.setConf( 1, 0, 1 );
-		if (err)
-			Serial.print("Can't set config to 1\n");
-
-		Usb.setUsbTaskState( USB_STATE_RUNNING );
-
-		b1 = digitalRead(BUTTON1);
-		b2 = digitalRead(BUTTON2);
-		b3 = digitalRead(BUTTON3);
-		c = captouched();
-
-		while(1) {
-			int len = Usb.newInTransfer(1, inEp.epAddr, sizeof(usbBuff),
-						    (char *)usbBuff);
-			/* int i; */
-			/* byte b; */
-			/* byte msg[3]; */
-			/* msg[0] = 0x1; */
-
-			if (len > 0) {
-				// XXX: assumes only one command per packet
-				if (usbBuff[0] == 0x2) {
-					if (usbBuff[1] == 0x0)
-						analogWrite( LED1_RED, 255 - usbBuff[2]);
-					else if (usbBuff[1] == 0x1)
-						analogWrite( LED1_GREEN, 255 - usbBuff[2]);
-					else if (usbBuff[1] == 0x2)
-						analogWrite( LED1_BLUE, 255 - usbBuff[2]);
-					else if (usbBuff[1] == 0x3)
-						analogWrite( LED2_RED, 255 - usbBuff[2]);
-					else if (usbBuff[1] == 0x4)
-						analogWrite( LED2_GREEN, 255 - usbBuff[2]);
-					else if (usbBuff[1] == 0x5)
-						analogWrite( LED2_BLUE, 255 - usbBuff[2]);
-					else if (usbBuff[1] == 0x6)
-						analogWrite( LED3_RED, 255 - usbBuff[2]);
-					else if (usbBuff[1] == 0x7)
-						analogWrite( LED3_GREEN, 255 - usbBuff[2]);
-					else if (usbBuff[1] == 0x8)
-						analogWrite( LED3_BLUE, 255 - usbBuff[2]);
-					else if (usbBuff[1] == 0x10)
-						servos[0].write(map(usbBuff[2], 0, 255, 0, 180));
-					else if (usbBuff[1] == 0x11)
-						servos[1].write(map(usbBuff[2], 0, 255, 0, 180));
-					else if (usbBuff[1] == 0x12)
-						servos[2].write(map(usbBuff[2], 0, 255, 0, 180));
-				} else if (usbBuff[0] == 0x3) {
-					if (usbBuff[1] == 0x0)
-						digitalWrite( RELAY1, usbBuff[2] ? HIGH : LOW );
-					else if (usbBuff[1] == 0x1)
-						digitalWrite( RELAY2, usbBuff[2] ? HIGH : LOW );
-
-				}
-
-//				for (i = 0; i < len; i++)
-//				Serial.print('\n');
-			}
-
-
-		}
-
-	}
-
-}
-
-
-void loop()
-{
-	USB_DEVICE_DESCRIPTOR *devDesc = (USB_DEVICE_DESCRIPTOR *) usbBuff;
-	byte err;
-
-	Max.Task();
-	Usb.Task();
-	if( Usb.getUsbTaskState() >= USB_STATE_CONFIGURING ) {
-		Serial.print("\nDevice addressed... ");
-		Serial.print("Requesting device descriptor.");
-
-		err = Usb.getDevDescr(1, 0, 0x12, (char *) devDesc);
-		if (err) {
-			Serial.print("\nDevice descriptor cannot be retrieved. Program Halted\n");
-			while(1);
-		}
-
-		if (isAndroidVendor(devDesc)) {
-			Serial.print("found android device\n");
-
-			if (isAccessoryDevice(devDesc)) {
-				Serial.print("found android acessory device\n");
-				doAndroid();
-			} else {
-				Serial.print("found possible device. swithcing to serial mode\n");
-				switchDevice(1);
-			}
-		}
-
-		while (Usb.getUsbTaskState() != USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) {
-			Max.Task();
-			Usb.Task();
-
-
-		}
-
-		Serial.print("detached\n");
-
-	}
-
-}
-
-// ==============================================================================
-// Austria Microsystems i2c Joystick
-
-/*
-  If a threshold is provided, the dead zone will be programmed such that interrupts will not
-  be generated unless the threshold is exceeded.
-
-  Note that if you use that mode, you will have to use passage of time with no new interrupts
-  to detect that the stick has been released and has returned to center.
-  
-  If you need to explicitly track return to center, pass 0 as the threshold.  "Center" will
-  still bounce around a little 
-*/
-
-
-void init_joystick( int threshold )
-{
-  byte status = 0;
-  
-  pinMode( JOY_SWITCH, INPUT );
-  digitalWrite( JOY_SWITCH, HIGH );    // enable the internal pullup
-  
-  pinMode( JOY_nINT, INPUT );
-  digitalWrite( JOY_nINT, HIGH );      // enable the internal pullup
-
-  pinMode( JOY_nRESET, OUTPUT );
-
-  digitalWrite( JOY_nRESET, 1 );
-  delay(1);
-  digitalWrite( JOY_nRESET, 0 );
-  delay(1);
-  digitalWrite( JOY_nRESET, 1 );
-
-  Wire.begin();
-  
-  do {
-    status = read_joy_reg( 0x0f );        // XXX need timeout
-  } while ((status & 0xf0) != 0xf0);
-  
-  write_joy_reg( 0x2e, 0x86 );            // invert magnet polarity setting, per datasheet
-
-  calibrate_joystick( threshold );        // calibrate & set up dead zone area  
-}
-
-
-int offset_X, offset_Y;
-
-void calibrate_joystick( int dz )
-{
-  char iii;
-  int x_cal = 0;
-  int y_cal = 0;
-
-  write_joy_reg( 0x0f, 0x00 );          // Low Power Mode, 20ms auto wakeup
-                                        // INTn output enabled
-                                        // INTn active after each measurement
-                                        // Normal (non-Reset) mode
-  delay(1);
-
-  read_joy_reg( 0x11 );                 // dummy read of Y_reg to reset interrupt
-
-  for( iii = 0; iii != 16; iii++ ) {    // read coords 16 times & average 
-    while( !joystick_interrupt() )      // poll for interrupt
-      ;
-    x_cal += read_joy_reg( 0x10 );      // X pos
-    y_cal += read_joy_reg( 0x11 );      // Y pos
-  }
-  
-  offset_X = -(x_cal>>4);               // divide by 16 to get average
-  offset_Y = -(y_cal>>4);
-  
-  //sprintf(msgbuf, "offsets = %d, %d\n", offset_X, offset_Y);
-  //Serial.print(msgbuf);
-  
-  write_joy_reg( 0x12,  dz - offset_X );  // Xp, LEFT threshold for INTn
-  write_joy_reg( 0x13, -dz - offset_X );  // Xn, RIGHT threshold for INTn
-  write_joy_reg( 0x14,  dz - offset_Y );  // Yp, UP threshold for INTn
-  write_joy_reg( 0x15, -dz - offset_Y );  // Yn, DOWN threshold for INTn
-
-  if ( dz )                             // dead zone threshold detect requested?
-    write_joy_reg( 0x0f, 0x04 );          // Low Power Mode, 20ms auto wakeup
-                                          // INTn output enabled
-                                          // INTn active when movement exceeds dead zone
-                                          // Normal (non-Reset) mode
-}
-
-
-void read_joystick( int *x, int *y )
-{
-  *x = read_joy_reg( 0x10 ) + offset_X;
-  *y = read_joy_reg( 0x11 ) + offset_Y;  // reading Y clears the interrupt
-}
-
-char joystick_interrupt()
-{
-  return ( digitalRead( JOY_nINT ) == 0 ); 
-}
-
-
-#define  JOY_I2C_ADDR    0x40
-
-char read_joy_reg( char reg_addr )
-{
-  char c;
-  
-  Wire.beginTransmission( JOY_I2C_ADDR );
-  Wire.send( reg_addr );
-  Wire.endTransmission();
-  
-  Wire.requestFrom( JOY_I2C_ADDR, 1 );
-  
-  while(Wire.available())
-    c = Wire.receive();
-  
-  return c;
-}
-
-void write_joy_reg( char reg_addr, char val )
-{
-  Wire.beginTransmission( JOY_I2C_ADDR );
-  Wire.send( reg_addr );
-  Wire.send( val );
-  Wire.endTransmission();  
-}
-
-/* Capacitive touch technique from Mario Becker, Fraunhofer IGD, 2007 http://www.igd.fhg.de/igd-a4 */
-
-char captouched() 
-{
-  char iii, jjj, retval;
-  
-  retval = 0;
-  
-  for( jjj = 0; jjj != 10; jjj++ ) {
-    delay( 10 );
-  
-    pinMode( TOUCH, INPUT );
-    digitalWrite( TOUCH, HIGH );
-  
-    for ( iii = 0; iii <  16; iii++ )
-      if( digitalRead( TOUCH ) )
-        break;
-      
-    digitalWrite( TOUCH, LOW );
-    pinMode( TOUCH, OUTPUT );
-  
-    retval += iii;
-  }
-  
-  return retval;
-}