diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..5391305
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2012 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.
+#
+
+# don't build uiautomator in unbundled env
+ifndef TARGET_BUILD_APPS
+include $(call all-subdir-makefiles)
+else
+ifneq ($(filter uiautomator,$(TARGET_BUILD_APPS)),)
+# used by the platform apps build.
+include $(call all-subdir-makefiles)
+endif
+endif
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/api/16.txt b/api/16.txt
new file mode 100644
index 0000000..f3b0eb7
--- /dev/null
+++ b/api/16.txt
@@ -0,0 +1,174 @@
+package com.android.uiautomator.core {
+
+  public class UiCollection extends com.android.uiautomator.core.UiObject {
+    ctor public UiCollection(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByInstance(com.android.uiautomator.core.UiSelector, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount(com.android.uiautomator.core.UiSelector);
+  }
+
+  public class UiDevice {
+    method public void clearLastTraversedText();
+    method public boolean click(int, int);
+    method public void dumpWindowHierarchy(java.lang.String);
+    method public void freezeRotation() throws android.os.RemoteException;
+    method public java.lang.String getCurrentActivityName();
+    method public java.lang.String getCurrentPackageName();
+    method public int getDisplayHeight();
+    method public int getDisplayWidth();
+    method public static com.android.uiautomator.core.UiDevice getInstance();
+    method public java.lang.String getLastTraversedText();
+    method public boolean hasAnyWatcherTriggered();
+    method public boolean hasWatcherTriggered(java.lang.String);
+    method public boolean isScreenOn() throws android.os.RemoteException;
+    method public boolean pressBack();
+    method public boolean pressDPadCenter();
+    method public boolean pressDPadDown();
+    method public boolean pressDPadLeft();
+    method public boolean pressDPadRight();
+    method public boolean pressDPadUp();
+    method public boolean pressDelete();
+    method public boolean pressEnter();
+    method public boolean pressHome();
+    method public boolean pressKeyCode(int);
+    method public boolean pressKeyCode(int, int);
+    method public boolean pressMenu();
+    method public boolean pressRecentApps() throws android.os.RemoteException;
+    method public boolean pressSearch();
+    method public void registerWatcher(java.lang.String, com.android.uiautomator.core.UiWatcher);
+    method public void removeWatcher(java.lang.String);
+    method public void resetWatcherTriggers();
+    method public void runWatchers();
+    method public void sleep() throws android.os.RemoteException;
+    method public boolean swipe(int, int, int, int, int);
+    method public boolean swipe(android.graphics.Point[], int);
+    method public void unfreezeRotation() throws android.os.RemoteException;
+    method public void waitForIdle();
+    method public void waitForIdle(long);
+    method public boolean waitForWindowUpdate(java.lang.String, long);
+    method public void wakeUp() throws android.os.RemoteException;
+  }
+
+  public class UiObject {
+    ctor public UiObject(com.android.uiautomator.core.UiSelector);
+    method public void clearTextField() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean click() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow(long) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean exists();
+    method protected android.view.accessibility.AccessibilityNodeInfo findAccessibilityNodeInfo(long);
+    method public android.graphics.Rect getBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChild(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getContentDescription() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getFromParent(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getPackageName() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public final com.android.uiautomator.core.UiSelector getSelector();
+    method public java.lang.String getText() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isCheckable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isChecked() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isEnabled() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocusable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocused() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isLongClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isScrollable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isSelected() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClick() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean setText(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeDown(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeLeft(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeRight(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeUp(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean waitForExists(long);
+    method public boolean waitUntilGone(long);
+    field protected static final int SWIPE_MARGIN_LIMIT = 5; // 0x5
+    field protected static final long WAIT_FOR_SELECTOR_POLL = 1000L; // 0x3e8L
+    field protected static final long WAIT_FOR_SELECTOR_TIMEOUT = 10000L; // 0x2710L
+    field protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500L; // 0x157cL
+  }
+
+  public class UiObjectNotFoundException extends java.lang.Exception {
+    ctor public UiObjectNotFoundException(java.lang.String);
+    ctor public UiObjectNotFoundException(java.lang.String, java.lang.Throwable);
+    ctor public UiObjectNotFoundException(java.lang.Throwable);
+  }
+
+  public class UiScrollable extends com.android.uiautomator.core.UiCollection {
+    ctor public UiScrollable(com.android.uiautomator.core.UiSelector);
+    method protected boolean exists(com.android.uiautomator.core.UiSelector);
+    method public boolean flingBackward();
+    method public boolean flingForward();
+    method public boolean flingToBeginning(int);
+    method public boolean flingToEnd(int);
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getMaxSearchSwipes();
+    method public double getSwipeDeadZonePercentage();
+    method public boolean scrollBackward();
+    method public boolean scrollBackward(int);
+    method public boolean scrollDescriptionIntoView(java.lang.String);
+    method public boolean scrollForward();
+    method public boolean scrollForward(int);
+    method public boolean scrollIntoView(com.android.uiautomator.core.UiSelector);
+    method public boolean scrollTextIntoView(java.lang.String);
+    method public boolean scrollToBeginning(int, int);
+    method public boolean scrollToBeginning(int);
+    method public boolean scrollToEnd(int, int);
+    method public boolean scrollToEnd(int);
+    method public void setAsHorizontalList();
+    method public void setAsVerticalList();
+    method public void setMaxSearchSwipes(int);
+    method public void setSwipeDeadZonePercentage(double);
+  }
+
+  public class UiSelector {
+    ctor public UiSelector();
+    method public com.android.uiautomator.core.UiSelector checked(boolean);
+    method public com.android.uiautomator.core.UiSelector childSelector(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector className(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector clickable(boolean);
+    method public com.android.uiautomator.core.UiSelector description(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionStartsWith(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector enabled(boolean);
+    method public com.android.uiautomator.core.UiSelector focusable(boolean);
+    method public com.android.uiautomator.core.UiSelector focused(boolean);
+    method public com.android.uiautomator.core.UiSelector fromParent(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector index(int);
+    method public com.android.uiautomator.core.UiSelector instance(int);
+    method public com.android.uiautomator.core.UiSelector packageName(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector scrollable(boolean);
+    method public com.android.uiautomator.core.UiSelector selected(boolean);
+    method public com.android.uiautomator.core.UiSelector text(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textStartsWith(java.lang.String);
+  }
+
+  public abstract interface UiWatcher {
+    method public abstract boolean checkForCondition();
+  }
+
+}
+
+package com.android.uiautomator.testrunner {
+
+  public abstract interface IAutomationSupport {
+    method public abstract void sendStatus(int, android.os.Bundle);
+  }
+
+  public class UiAutomatorTestCase extends junit.framework.TestCase {
+    ctor public UiAutomatorTestCase();
+    method public com.android.uiautomator.testrunner.IAutomationSupport getAutomationSupport();
+    method public android.os.Bundle getParams();
+    method public com.android.uiautomator.core.UiDevice getUiDevice();
+    method public void sleep(long);
+  }
+
+}
+
diff --git a/api/17.txt b/api/17.txt
new file mode 100644
index 0000000..a1d80c4
--- /dev/null
+++ b/api/17.txt
@@ -0,0 +1,192 @@
+package com.android.uiautomator.core {
+
+  public class UiCollection extends com.android.uiautomator.core.UiObject {
+    ctor public UiCollection(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByInstance(com.android.uiautomator.core.UiSelector, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount(com.android.uiautomator.core.UiSelector);
+  }
+
+  public class UiDevice {
+    method public void clearLastTraversedText();
+    method public boolean click(int, int);
+    method public void dumpWindowHierarchy(java.lang.String);
+    method public void freezeRotation() throws android.os.RemoteException;
+    method public deprecated java.lang.String getCurrentActivityName();
+    method public java.lang.String getCurrentPackageName();
+    method public int getDisplayHeight();
+    method public int getDisplayRotation();
+    method public int getDisplayWidth();
+    method public static com.android.uiautomator.core.UiDevice getInstance();
+    method public java.lang.String getLastTraversedText();
+    method public java.lang.String getProductName();
+    method public boolean hasAnyWatcherTriggered();
+    method public boolean hasWatcherTriggered(java.lang.String);
+    method public boolean isNaturalOrientation();
+    method public boolean isScreenOn() throws android.os.RemoteException;
+    method public boolean pressBack();
+    method public boolean pressDPadCenter();
+    method public boolean pressDPadDown();
+    method public boolean pressDPadLeft();
+    method public boolean pressDPadRight();
+    method public boolean pressDPadUp();
+    method public boolean pressDelete();
+    method public boolean pressEnter();
+    method public boolean pressHome();
+    method public boolean pressKeyCode(int);
+    method public boolean pressKeyCode(int, int);
+    method public boolean pressMenu();
+    method public boolean pressRecentApps() throws android.os.RemoteException;
+    method public boolean pressSearch();
+    method public void registerWatcher(java.lang.String, com.android.uiautomator.core.UiWatcher);
+    method public void removeWatcher(java.lang.String);
+    method public void resetWatcherTriggers();
+    method public void runWatchers();
+    method public void setOrientationLeft() throws android.os.RemoteException;
+    method public void setOrientationNatural() throws android.os.RemoteException;
+    method public void setOrientationRight() throws android.os.RemoteException;
+    method public void sleep() throws android.os.RemoteException;
+    method public boolean swipe(int, int, int, int, int);
+    method public boolean swipe(android.graphics.Point[], int);
+    method public boolean takeScreenshot(java.io.File);
+    method public boolean takeScreenshot(java.io.File, float, int);
+    method public void unfreezeRotation() throws android.os.RemoteException;
+    method public void waitForIdle();
+    method public void waitForIdle(long);
+    method public boolean waitForWindowUpdate(java.lang.String, long);
+    method public void wakeUp() throws android.os.RemoteException;
+  }
+
+  public class UiObject {
+    ctor public UiObject(com.android.uiautomator.core.UiSelector);
+    method public void clearTextField() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean click() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow(long) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean exists();
+    method protected android.view.accessibility.AccessibilityNodeInfo findAccessibilityNodeInfo(long);
+    method public android.graphics.Rect getBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChild(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getContentDescription() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getFromParent(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getPackageName() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public final com.android.uiautomator.core.UiSelector getSelector();
+    method public java.lang.String getText() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public android.graphics.Rect getVisibleBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isCheckable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isChecked() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isEnabled() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocusable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocused() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isLongClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isScrollable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isSelected() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClick() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean setText(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeDown(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeLeft(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeRight(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeUp(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean waitForExists(long);
+    method public boolean waitUntilGone(long);
+    field protected static final int SWIPE_MARGIN_LIMIT = 5; // 0x5
+    field protected static final long WAIT_FOR_EVENT_TMEOUT = 3000L; // 0xbb8L
+    field protected static final long WAIT_FOR_SELECTOR_POLL = 1000L; // 0x3e8L
+    field protected static final long WAIT_FOR_SELECTOR_TIMEOUT = 10000L; // 0x2710L
+    field protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500L; // 0x157cL
+  }
+
+  public class UiObjectNotFoundException extends java.lang.Exception {
+    ctor public UiObjectNotFoundException(java.lang.String);
+    ctor public UiObjectNotFoundException(java.lang.String, java.lang.Throwable);
+    ctor public UiObjectNotFoundException(java.lang.Throwable);
+  }
+
+  public class UiScrollable extends com.android.uiautomator.core.UiCollection {
+    ctor public UiScrollable(com.android.uiautomator.core.UiSelector);
+    method protected boolean exists(com.android.uiautomator.core.UiSelector);
+    method public boolean flingBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getMaxSearchSwipes();
+    method public double getSwipeDeadZonePercentage();
+    method public boolean scrollBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollBackward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollDescriptionIntoView(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollForward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollIntoView(com.android.uiautomator.core.UiObject) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollIntoView(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollTextIntoView(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiScrollable setAsHorizontalList();
+    method public com.android.uiautomator.core.UiScrollable setAsVerticalList();
+    method public com.android.uiautomator.core.UiScrollable setMaxSearchSwipes(int);
+    method public com.android.uiautomator.core.UiScrollable setSwipeDeadZonePercentage(double);
+  }
+
+  public class UiSelector {
+    ctor public UiSelector();
+    method public com.android.uiautomator.core.UiSelector checked(boolean);
+    method public com.android.uiautomator.core.UiSelector childSelector(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector className(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector className(java.lang.Class<T>);
+    method public com.android.uiautomator.core.UiSelector classNameMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector clickable(boolean);
+    method protected com.android.uiautomator.core.UiSelector cloneSelector();
+    method public com.android.uiautomator.core.UiSelector description(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionStartsWith(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector enabled(boolean);
+    method public com.android.uiautomator.core.UiSelector focusable(boolean);
+    method public com.android.uiautomator.core.UiSelector focused(boolean);
+    method public com.android.uiautomator.core.UiSelector fromParent(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector index(int);
+    method public com.android.uiautomator.core.UiSelector instance(int);
+    method public com.android.uiautomator.core.UiSelector longClickable(boolean);
+    method public com.android.uiautomator.core.UiSelector packageName(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector packageNameMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector scrollable(boolean);
+    method public com.android.uiautomator.core.UiSelector selected(boolean);
+    method public com.android.uiautomator.core.UiSelector text(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textStartsWith(java.lang.String);
+  }
+
+  public abstract interface UiWatcher {
+    method public abstract boolean checkForCondition();
+  }
+
+}
+
+package com.android.uiautomator.testrunner {
+
+  public abstract interface IAutomationSupport {
+    method public abstract void sendStatus(int, android.os.Bundle);
+  }
+
+  public class UiAutomatorTestCase extends junit.framework.TestCase {
+    ctor public UiAutomatorTestCase();
+    method public com.android.uiautomator.testrunner.IAutomationSupport getAutomationSupport();
+    method public android.os.Bundle getParams();
+    method public com.android.uiautomator.core.UiDevice getUiDevice();
+    method public void sleep(long);
+  }
+
+}
+
diff --git a/api/current.txt b/api/current.txt
new file mode 100644
index 0000000..7eeecf5
--- /dev/null
+++ b/api/current.txt
@@ -0,0 +1,222 @@
+package com.android.uiautomator.core {
+
+  public final class Configurator {
+    method public long getActionAcknowledgmentTimeout();
+    method public static com.android.uiautomator.core.Configurator getInstance();
+    method public long getKeyInjectionDelay();
+    method public long getScrollAcknowledgmentTimeout();
+    method public long getWaitForIdleTimeout();
+    method public long getWaitForSelectorTimeout();
+    method public com.android.uiautomator.core.Configurator setActionAcknowledgmentTimeout(long);
+    method public com.android.uiautomator.core.Configurator setKeyInjectionDelay(long);
+    method public com.android.uiautomator.core.Configurator setScrollAcknowledgmentTimeout(long);
+    method public com.android.uiautomator.core.Configurator setWaitForIdleTimeout(long);
+    method public com.android.uiautomator.core.Configurator setWaitForSelectorTimeout(long);
+  }
+
+  public class UiCollection extends com.android.uiautomator.core.UiObject {
+    ctor public UiCollection(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByInstance(com.android.uiautomator.core.UiSelector, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount(com.android.uiautomator.core.UiSelector);
+  }
+
+  public class UiDevice {
+    method public void clearLastTraversedText();
+    method public boolean click(int, int);
+    method public boolean drag(int, int, int, int, int);
+    method public void dumpWindowHierarchy(java.lang.String);
+    method public void freezeRotation() throws android.os.RemoteException;
+    method public deprecated java.lang.String getCurrentActivityName();
+    method public java.lang.String getCurrentPackageName();
+    method public int getDisplayHeight();
+    method public int getDisplayRotation();
+    method public android.graphics.Point getDisplaySizeDp();
+    method public int getDisplayWidth();
+    method public static com.android.uiautomator.core.UiDevice getInstance();
+    method public java.lang.String getLastTraversedText();
+    method public java.lang.String getProductName();
+    method public boolean hasAnyWatcherTriggered();
+    method public boolean hasWatcherTriggered(java.lang.String);
+    method public boolean isNaturalOrientation();
+    method public boolean isScreenOn() throws android.os.RemoteException;
+    method public boolean openNotification();
+    method public boolean openQuickSettings();
+    method public boolean pressBack();
+    method public boolean pressDPadCenter();
+    method public boolean pressDPadDown();
+    method public boolean pressDPadLeft();
+    method public boolean pressDPadRight();
+    method public boolean pressDPadUp();
+    method public boolean pressDelete();
+    method public boolean pressEnter();
+    method public boolean pressHome();
+    method public boolean pressKeyCode(int);
+    method public boolean pressKeyCode(int, int);
+    method public boolean pressMenu();
+    method public boolean pressRecentApps() throws android.os.RemoteException;
+    method public boolean pressSearch();
+    method public void registerWatcher(java.lang.String, com.android.uiautomator.core.UiWatcher);
+    method public void removeWatcher(java.lang.String);
+    method public void resetWatcherTriggers();
+    method public void runWatchers();
+    method public void setCompressedLayoutHeirarchy(boolean);
+    method public void setOrientationLeft() throws android.os.RemoteException;
+    method public void setOrientationNatural() throws android.os.RemoteException;
+    method public void setOrientationRight() throws android.os.RemoteException;
+    method public void sleep() throws android.os.RemoteException;
+    method public boolean swipe(int, int, int, int, int);
+    method public boolean swipe(android.graphics.Point[], int);
+    method public boolean takeScreenshot(java.io.File);
+    method public boolean takeScreenshot(java.io.File, float, int);
+    method public void unfreezeRotation() throws android.os.RemoteException;
+    method public void waitForIdle();
+    method public void waitForIdle(long);
+    method public boolean waitForWindowUpdate(java.lang.String, long);
+    method public void wakeUp() throws android.os.RemoteException;
+  }
+
+  public class UiObject {
+    ctor public UiObject(com.android.uiautomator.core.UiSelector);
+    method public void clearTextField() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean click() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow(long) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean dragTo(com.android.uiautomator.core.UiObject, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean dragTo(int, int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean exists();
+    method protected android.view.accessibility.AccessibilityNodeInfo findAccessibilityNodeInfo(long);
+    method public android.graphics.Rect getBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChild(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getClassName() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getContentDescription() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getFromParent(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getPackageName() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public final com.android.uiautomator.core.UiSelector getSelector();
+    method public java.lang.String getText() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public android.graphics.Rect getVisibleBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isCheckable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isChecked() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isEnabled() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocusable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocused() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isLongClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isScrollable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isSelected() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClick() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean performMultiPointerGesture(android.view.MotionEvent.PointerCoords...);
+    method public boolean performTwoPointerGesture(android.graphics.Point, android.graphics.Point, android.graphics.Point, android.graphics.Point, int);
+    method public boolean pinchIn(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean pinchOut(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean setText(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeDown(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeLeft(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeRight(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeUp(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean waitForExists(long);
+    method public boolean waitUntilGone(long);
+    field protected static final int FINGER_TOUCH_HALF_WIDTH = 20; // 0x14
+    field protected static final int SWIPE_MARGIN_LIMIT = 5; // 0x5
+    field protected static final deprecated long WAIT_FOR_EVENT_TMEOUT = 3000L; // 0xbb8L
+    field protected static final long WAIT_FOR_SELECTOR_POLL = 1000L; // 0x3e8L
+    field protected static final deprecated long WAIT_FOR_SELECTOR_TIMEOUT = 10000L; // 0x2710L
+    field protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500L; // 0x157cL
+  }
+
+  public class UiObjectNotFoundException extends java.lang.Exception {
+    ctor public UiObjectNotFoundException(java.lang.String);
+    ctor public UiObjectNotFoundException(java.lang.String, java.lang.Throwable);
+    ctor public UiObjectNotFoundException(java.lang.Throwable);
+  }
+
+  public class UiScrollable extends com.android.uiautomator.core.UiCollection {
+    ctor public UiScrollable(com.android.uiautomator.core.UiSelector);
+    method protected boolean exists(com.android.uiautomator.core.UiSelector);
+    method public boolean flingBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getMaxSearchSwipes();
+    method public double getSwipeDeadZonePercentage();
+    method public boolean scrollBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollBackward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollDescriptionIntoView(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollForward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollIntoView(com.android.uiautomator.core.UiObject) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollIntoView(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollTextIntoView(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiScrollable setAsHorizontalList();
+    method public com.android.uiautomator.core.UiScrollable setAsVerticalList();
+    method public com.android.uiautomator.core.UiScrollable setMaxSearchSwipes(int);
+    method public com.android.uiautomator.core.UiScrollable setSwipeDeadZonePercentage(double);
+  }
+
+  public class UiSelector {
+    ctor public UiSelector();
+    method public com.android.uiautomator.core.UiSelector checkable(boolean);
+    method public com.android.uiautomator.core.UiSelector checked(boolean);
+    method public com.android.uiautomator.core.UiSelector childSelector(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector className(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector className(java.lang.Class<T>);
+    method public com.android.uiautomator.core.UiSelector classNameMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector clickable(boolean);
+    method protected com.android.uiautomator.core.UiSelector cloneSelector();
+    method public com.android.uiautomator.core.UiSelector description(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionStartsWith(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector enabled(boolean);
+    method public com.android.uiautomator.core.UiSelector focusable(boolean);
+    method public com.android.uiautomator.core.UiSelector focused(boolean);
+    method public com.android.uiautomator.core.UiSelector fromParent(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector index(int);
+    method public com.android.uiautomator.core.UiSelector instance(int);
+    method public com.android.uiautomator.core.UiSelector longClickable(boolean);
+    method public com.android.uiautomator.core.UiSelector packageName(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector packageNameMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector resourceId(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector resourceIdMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector scrollable(boolean);
+    method public com.android.uiautomator.core.UiSelector selected(boolean);
+    method public com.android.uiautomator.core.UiSelector text(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textStartsWith(java.lang.String);
+  }
+
+  public abstract interface UiWatcher {
+    method public abstract boolean checkForCondition();
+  }
+
+}
+
+package com.android.uiautomator.testrunner {
+
+  public abstract interface IAutomationSupport {
+    method public abstract void sendStatus(int, android.os.Bundle);
+  }
+
+  public class UiAutomatorTestCase extends junit.framework.TestCase {
+    ctor public UiAutomatorTestCase();
+    method public com.android.uiautomator.testrunner.IAutomationSupport getAutomationSupport();
+    method public android.os.Bundle getParams();
+    method public com.android.uiautomator.core.UiDevice getUiDevice();
+    method public void sleep(long);
+  }
+
+}
+
diff --git a/cmds/Android.mk b/cmds/Android.mk
new file mode 100644
index 0000000..c141484
--- /dev/null
+++ b/cmds/Android.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2012 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.
+#
+
+include $(call all-subdir-makefiles)
diff --git a/cmds/uiautomator/Android.mk b/cmds/uiautomator/Android.mk
new file mode 100644
index 0000000..5c91b52
--- /dev/null
+++ b/cmds/uiautomator/Android.mk
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2012 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := uiautomator.core
+LOCAL_MODULE := uiautomator
+
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := uiautomator
+LOCAL_SRC_FILES := uiautomator
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_PREBUILT)
diff --git a/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java b/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java
new file mode 100644
index 0000000..c35f7fc
--- /dev/null
+++ b/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2012 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.android.commands.uiautomator;
+
+import android.app.UiAutomation;
+import android.graphics.Point;
+import android.hardware.display.DisplayManagerGlobal;
+import android.os.Environment;
+import android.view.Display;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.android.commands.uiautomator.Launcher.Command;
+import com.android.uiautomator.core.AccessibilityNodeInfoDumper;
+import com.android.uiautomator.core.UiAutomationShellWrapper;
+
+import java.io.File;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Implementation of the dump subcommand
+ *
+ * This creates an XML dump of current UI hierarchy
+ */
+public class DumpCommand extends Command {
+
+    private static final File DEFAULT_DUMP_FILE = new File(
+            Environment.getLegacyExternalStorageDirectory(), "window_dump.xml");
+
+    public DumpCommand() {
+        super("dump");
+    }
+
+    @Override
+    public String shortHelp() {
+        return "creates an XML dump of current UI hierarchy";
+    }
+
+    @Override
+    public String detailedOptions() {
+        return "    dump [--verbose][file]\n"
+            + "      [--compressed]: dumps compressed layout information.\n"
+            + "      [file]: the location where the dumped XML should be stored, default is\n      "
+            + DEFAULT_DUMP_FILE.getAbsolutePath() + "\n";
+    }
+
+    @Override
+    public void run(String[] args) {
+        File dumpFile = DEFAULT_DUMP_FILE;
+        boolean verboseMode = true;
+
+        for (String arg : args) {
+            if (arg.equals("--compressed"))
+                verboseMode = false;
+            else if (!arg.startsWith("-")) {
+                dumpFile = new File(arg);
+            }
+        }
+
+        UiAutomationShellWrapper automationWrapper = new UiAutomationShellWrapper();
+        automationWrapper.connect();
+        if (verboseMode) {
+            // default
+            automationWrapper.setCompressedLayoutHierarchy(false);
+        } else {
+            automationWrapper.setCompressedLayoutHierarchy(true);
+        }
+
+        // It appears that the bridge needs time to be ready. Making calls to the
+        // bridge immediately after connecting seems to cause exceptions. So let's also
+        // do a wait for idle in case the app is busy.
+        try {
+            UiAutomation uiAutomation = automationWrapper.getUiAutomation();
+            uiAutomation.waitForIdle(1000, 1000 * 10);
+            AccessibilityNodeInfo info = uiAutomation.getRootInActiveWindow();
+            if (info == null) {
+                System.err.println("ERROR: null root node returned by UiTestAutomationBridge.");
+                return;
+            }
+
+            Display display =
+                    DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
+            int rotation = display.getRotation();
+            Point size = new Point();
+            display.getSize(size);
+            AccessibilityNodeInfoDumper.dumpWindowToFile(info, dumpFile, rotation, size.x, size.y);
+        } catch (TimeoutException re) {
+            System.err.println("ERROR: could not get idle state.");
+            return;
+        } finally {
+            automationWrapper.disconnect();
+        }
+        System.out.println(
+                String.format("UI hierchary dumped to: %s", dumpFile.getAbsolutePath()));
+    }
+}
diff --git a/cmds/uiautomator/src/com/android/commands/uiautomator/EventsCommand.java b/cmds/uiautomator/src/com/android/commands/uiautomator/EventsCommand.java
new file mode 100644
index 0000000..ce55f18
--- /dev/null
+++ b/cmds/uiautomator/src/com/android/commands/uiautomator/EventsCommand.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.android.commands.uiautomator;
+
+import android.app.UiAutomation.OnAccessibilityEventListener;
+import android.view.accessibility.AccessibilityEvent;
+
+import com.android.commands.uiautomator.Launcher.Command;
+import com.android.uiautomator.core.UiAutomationShellWrapper;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Implementation of the events subcommand
+ *
+ * Prints out accessibility events until process is stopped.
+ */
+public class EventsCommand extends Command {
+
+    private Object mQuitLock = new Object();
+
+    public EventsCommand() {
+        super("events");
+    }
+
+    @Override
+    public String shortHelp() {
+        return "prints out accessibility events until terminated";
+    }
+
+    @Override
+    public String detailedOptions() {
+        return null;
+    }
+
+    @Override
+    public void run(String[] args) {
+        UiAutomationShellWrapper automationWrapper = new UiAutomationShellWrapper();
+        automationWrapper.connect();
+        automationWrapper.getUiAutomation().setOnAccessibilityEventListener(
+                new OnAccessibilityEventListener() {
+            @Override
+            public void onAccessibilityEvent(AccessibilityEvent event) {
+                SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+                System.out.println(String.format("%s %s",
+                        formatter.format(new Date()), event.toString()));
+            }
+        });
+        // there's really no way to stop, essentially we just block indefinitely here and wait
+        // for user to press Ctrl+C
+        synchronized (mQuitLock) {
+            try {
+                mQuitLock.wait();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        automationWrapper.disconnect();
+    }
+}
diff --git a/cmds/uiautomator/src/com/android/commands/uiautomator/Launcher.java b/cmds/uiautomator/src/com/android/commands/uiautomator/Launcher.java
new file mode 100644
index 0000000..bc1d948
--- /dev/null
+++ b/cmds/uiautomator/src/com/android/commands/uiautomator/Launcher.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2012 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.android.commands.uiautomator;
+
+import android.os.Process;
+
+import java.util.Arrays;
+
+/**
+ * Entry point into the uiautomator command line
+ *
+ * This class maintains the list of sub commands, and redirect the control into it based on the
+ * command line arguments. It also prints out help arguments for each sub commands.
+ *
+ * To add a new sub command, implement {@link Command} and add an instance into COMMANDS array
+ */
+public class Launcher {
+
+    /**
+     * A simple abstraction class for supporting generic sub commands
+     */
+    public static abstract class Command {
+        private String mName;
+
+        public Command(String name) {
+            mName = name;
+        }
+
+        /**
+         * Returns the name of the sub command
+         * @return
+         */
+        public String name() {
+            return mName;
+        }
+
+        /**
+         * Returns a one-liner of the function of this command
+         * @return
+         */
+        public abstract String shortHelp();
+
+        /**
+         * Returns a detailed explanation of the command usage
+         *
+         * Usage may have multiple lines, indentation of 4 spaces recommended.
+         * @return
+         */
+        public abstract String detailedOptions();
+
+        /**
+         * Starts the command with the provided arguments
+         * @param args
+         */
+        public abstract void run(String args[]);
+    }
+
+    public static void main(String[] args) {
+        // show a meaningful process name in `ps`
+        Process.setArgV0("uiautomator");
+        if (args.length >= 1) {
+            Command command = findCommand(args[0]);
+            if (command != null) {
+                String[] args2 = {};
+                if (args.length > 1) {
+                    // consume the first arg
+                    args2 = Arrays.copyOfRange(args, 1, args.length);
+                }
+                command.run(args2);
+                return;
+            }
+        }
+        HELP_COMMAND.run(args);
+    }
+
+    private static Command findCommand(String name) {
+        for (Command command : COMMANDS) {
+            if (command.name().equals(name)) {
+                return command;
+            }
+        }
+        return null;
+    }
+
+    private static Command HELP_COMMAND = new Command("help") {
+        @Override
+        public void run(String[] args) {
+            System.err.println("Usage: uiautomator <subcommand> [options]\n");
+            System.err.println("Available subcommands:\n");
+            for (Command command : COMMANDS) {
+                String shortHelp = command.shortHelp();
+                String detailedOptions = command.detailedOptions();
+                if (shortHelp == null) {
+                    shortHelp = "";
+                }
+                if (detailedOptions == null) {
+                    detailedOptions = "";
+                }
+                System.err.println(String.format("%s: %s", command.name(), shortHelp));
+                System.err.println(detailedOptions);
+            }
+        }
+
+        @Override
+        public String detailedOptions() {
+            return null;
+        }
+
+        @Override
+        public String shortHelp() {
+            return "displays help message";
+        }
+    };
+
+    private static Command[] COMMANDS = new Command[] {
+        HELP_COMMAND,
+        new RunTestCommand(),
+        new DumpCommand(),
+        new EventsCommand(),
+    };
+}
\ No newline at end of file
diff --git a/cmds/uiautomator/src/com/android/commands/uiautomator/RunTestCommand.java b/cmds/uiautomator/src/com/android/commands/uiautomator/RunTestCommand.java
new file mode 100644
index 0000000..65611ab
--- /dev/null
+++ b/cmds/uiautomator/src/com/android/commands/uiautomator/RunTestCommand.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2012 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.android.commands.uiautomator;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.commands.uiautomator.Launcher.Command;
+import com.android.uiautomator.testrunner.UiAutomatorTestRunner;
+
+import dalvik.system.DexFile;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * Implementation of the runtest sub command
+ *
+ */
+public class RunTestCommand extends Command {
+    private static final String LOGTAG = RunTestCommand.class.getSimpleName();
+
+    private static final String OUTPUT_SIMPLE = "simple";
+    private static final String OUTPUT_FORMAT_KEY = "outputFormat";
+    private static final String CLASS_PARAM = "class";
+    private static final String JARS_PARAM = "jars";
+    private static final String DEBUG_PARAM = "debug";
+    private static final String RUNNER_PARAM = "runner";
+    private static final String CLASS_SEPARATOR = ",";
+    private static final String JARS_SEPARATOR = ":";
+    private static final int ARG_OK = 0;
+    private static final int ARG_FAIL_INCOMPLETE_E = -1;
+    private static final int ARG_FAIL_INCOMPLETE_C = -2;
+    private static final int ARG_FAIL_NO_CLASS = -3;
+    private static final int ARG_FAIL_RUNNER = -4;
+    private static final int ARG_FAIL_UNSUPPORTED = -99;
+
+    private final Bundle mParams = new Bundle();
+    private final List<String> mTestClasses = new ArrayList<String>();
+    private boolean mDebug;
+    private boolean mMonkey = false;
+    private String mRunnerClassName;
+    private UiAutomatorTestRunner mRunner;
+
+    public RunTestCommand() {
+        super("runtest");
+    }
+
+    @Override
+    public void run(String[] args) {
+        int ret = parseArgs(args);
+        switch (ret) {
+            case ARG_FAIL_INCOMPLETE_C:
+                System.err.println("Incomplete '-c' parameter.");
+                System.exit(ARG_FAIL_INCOMPLETE_C);
+                break;
+            case ARG_FAIL_INCOMPLETE_E:
+                System.err.println("Incomplete '-e' parameter.");
+                System.exit(ARG_FAIL_INCOMPLETE_E);
+                break;
+            case ARG_FAIL_UNSUPPORTED:
+                System.err.println("Unsupported standalone parameter.");
+                System.exit(ARG_FAIL_UNSUPPORTED);
+                break;
+            default:
+                break;
+        }
+        if (mTestClasses.isEmpty()) {
+            addTestClassesFromJars();
+            if (mTestClasses.isEmpty()) {
+                System.err.println("No test classes found.");
+                System.exit(ARG_FAIL_NO_CLASS);
+            }
+        }
+        getRunner().run(mTestClasses, mParams, mDebug, mMonkey);
+    }
+
+    private int parseArgs(String[] args) {
+        // we are parsing for these parameters:
+        // -e <key> <value>
+        // key-value pairs
+        // special ones are:
+        // key is "class", parameter is passed onto JUnit as class name to run
+        // key is "debug", parameter will determine whether to wait for debugger
+        // to attach
+        // -c <class name>
+        // -s turns on the simple output format
+        // equivalent to -e class <class name>, i.e. passed onto JUnit
+        for (int i = 0; i < args.length; i++) {
+            if (args[i].equals("-e")) {
+                if (i + 2 < args.length) {
+                    String key = args[++i];
+                    String value = args[++i];
+                    if (CLASS_PARAM.equals(key)) {
+                        addTestClasses(value);
+                    } else if (DEBUG_PARAM.equals(key)) {
+                        mDebug = "true".equals(value) || "1".equals(value);
+                    } else if (RUNNER_PARAM.equals(key)) {
+                        mRunnerClassName = value;
+                    } else {
+                        mParams.putString(key, value);
+                    }
+                } else {
+                    return ARG_FAIL_INCOMPLETE_E;
+                }
+            } else if (args[i].equals("-c")) {
+                if (i + 1 < args.length) {
+                    addTestClasses(args[++i]);
+                } else {
+                    return ARG_FAIL_INCOMPLETE_C;
+                }
+            } else if (args[i].equals("--monkey")) {
+                mMonkey = true;
+            } else if (args[i].equals("-s")) {
+                mParams.putString(OUTPUT_FORMAT_KEY, OUTPUT_SIMPLE);
+            } else {
+                return ARG_FAIL_UNSUPPORTED;
+            }
+        }
+        return ARG_OK;
+    }
+
+    protected UiAutomatorTestRunner getRunner() {
+        if (mRunner != null) {
+            return mRunner;
+        }
+
+        if (mRunnerClassName == null) {
+            mRunner = new UiAutomatorTestRunner();
+            return mRunner;
+        }
+        // use reflection to get the runner
+        Object o = null;
+        try {
+            Class<?> clazz = Class.forName(mRunnerClassName);
+            o = clazz.newInstance();
+        } catch (ClassNotFoundException cnfe) {
+            System.err.println("Cannot find runner: " + mRunnerClassName);
+            System.exit(ARG_FAIL_RUNNER);
+        } catch (InstantiationException ie) {
+            System.err.println("Cannot instantiate runner: " + mRunnerClassName);
+            System.exit(ARG_FAIL_RUNNER);
+        } catch (IllegalAccessException iae) {
+            System.err.println("Constructor of runner " + mRunnerClassName + " is not accessibile");
+            System.exit(ARG_FAIL_RUNNER);
+        }
+        try {
+            UiAutomatorTestRunner runner = (UiAutomatorTestRunner)o;
+            mRunner = runner;
+            return runner;
+        } catch (ClassCastException cce) {
+            System.err.println("Specified runner is not subclass of "
+                    + UiAutomatorTestRunner.class.getSimpleName());
+            System.exit(ARG_FAIL_RUNNER);
+        }
+        // won't reach here
+        return null;
+    }
+
+    /**
+     * Add test classes from a potentially comma separated list
+     * @param classes
+     */
+    private void addTestClasses(String classes) {
+        String[] classArray = classes.split(CLASS_SEPARATOR);
+        for (String clazz : classArray) {
+            mTestClasses.add(clazz);
+        }
+    }
+
+    /**
+     * Add test classes from jars passed on the command line. Use this if nothing was explicitly
+     * specified on the command line.
+     */
+    private void addTestClassesFromJars() {
+        String jars = mParams.getString(JARS_PARAM);
+        if (jars == null) return;
+
+        String[] jarFileNames = jars.split(JARS_SEPARATOR);
+        for (String fileName : jarFileNames) {
+            fileName = fileName.trim();
+            if (fileName.isEmpty()) continue;
+            try {
+                DexFile dexFile = new DexFile(fileName);
+                for(Enumeration<String> e = dexFile.entries(); e.hasMoreElements();) {
+                    String className = e.nextElement();
+                    if (isTestClass(className)) {
+                        mTestClasses.add(className);
+                    }
+                }
+                dexFile.close();
+            } catch (IOException e) {
+                Log.w(LOGTAG, String.format("Could not read %s: %s", fileName, e.getMessage()));
+            }
+        }
+    }
+
+    /**
+     * Tries to determine if a given class is a test class. A test class has to inherit from
+     * UiAutomator test case and it must be a top-level class.
+     * @param className
+     * @return
+     */
+    private boolean isTestClass(String className) {
+        try {
+            Class<?> clazz = this.getClass().getClassLoader().loadClass(className);
+            if (clazz.getEnclosingClass() != null) return false;
+            return getRunner().getTestCaseFilter().accept(clazz);
+        } catch (ClassNotFoundException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public String detailedOptions() {
+        return "    runtest <class spec> [options]\n"
+            + "    <class spec>: <JARS> < -c <CLASSES> | -e class <CLASSES> >\n"
+            + "      <JARS>: a list of jar files containing test classes and dependencies. If\n"
+            + "        the path is relative, it's assumed to be under /data/local/tmp. Use\n"
+            + "        absolute path if the file is elsewhere. Multiple files can be\n"
+            + "        specified, separated by space.\n"
+            + "      <CLASSES>: a list of test class names to run, separated by comma. To\n"
+            + "        a single method, use TestClass#testMethod format. The -e or -c option\n"
+            + "        may be repeated. This option is not required and if not provided then\n"
+            + "        all the tests in provided jars will be run automatically.\n"
+            + "    options:\n"
+            + "      --nohup: trap SIG_HUP, so test won't terminate even if parent process\n"
+            + "               is terminated, e.g. USB is disconnected.\n"
+            + "      -e debug [true|false]: wait for debugger to connect before starting.\n"
+            + "      -e runner [CLASS]: use specified test runner class instead. If\n"
+            + "        unspecified, framework default runner will be used.\n"
+            + "      -e <NAME> <VALUE>: other name-value pairs to be passed to test classes.\n"
+            + "        May be repeated.\n"
+            + "      -e outputFormat simple | -s: enabled less verbose JUnit style output.\n";
+    }
+
+    @Override
+    public String shortHelp() {
+        return "executes UI automation tests";
+    }
+
+}
diff --git a/cmds/uiautomator/uiautomator b/cmds/uiautomator/uiautomator
new file mode 100755
index 0000000..9aec2c4
--- /dev/null
+++ b/cmds/uiautomator/uiautomator
@@ -0,0 +1,120 @@
+#
+# Copyright (C) 2012 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.
+#
+# Script to start "uiautomator" on the device
+#
+# The script does a couple of things:
+# * Use an alternative dalvik cache when running as non-root. Jar file needs
+#   to be dexopt'd to run in Dalvik. For plain jar files, this is done at first
+#   use. shell user does not have write permission to default system Dalvik
+#   cache so we redirect to an alternative cache
+# * special processing for subcommand 'runtest':
+#    * '--nohup' allows process continue to run even if parent process that
+#      started it has already terminated. We parse for this parameter and set
+#      signal trap. This is useful for testing with USB disconnected
+#    * all jar files that the test classes resides in, or dependent on are
+#      provided on command line and exported to CLASSPATH environment variable
+#      before starting the Java code. This offloads the task of class loading
+#      and resolving of cross jar class dependency to Dalvik
+#    * all other subcommand or options are directly passed into Java code for
+#      further parsing
+
+export run_base=/data/local/tmp
+export base=/system
+
+# if not running as root, trick dalvik into using an alternative dex cache
+if [ ${USER_ID} -ne 0 ]; then
+  tmp_cache=${run_base}/dalvik-cache
+
+  if [ ! -d ${tmp_cache} ]; then
+    mkdir -p ${tmp_cache}
+  fi
+
+  export ANDROID_DATA=${run_base}
+fi
+
+# take first parameter as the command
+cmd=${1}
+
+if [ -z "${1}" ]; then
+  cmd="help"
+fi
+
+# strip the command parameter
+if [ -n "${1}" ]; then
+  shift
+fi
+
+CLASSPATH=/system/framework/android.test.runner.jar:${base}/framework/uiautomator.jar
+
+# eventually args will be what get passed down to Java code
+args=
+# we also pass the list of jar files, so we can extract class names for tests
+# if they are not explicitly specified
+jars=
+
+# special case pre-processing for 'runtest' command
+if [ "${cmd}" == "runtest" ]; then
+  # first parse the jar paths
+  while [ true ]; do
+    if [ -z "${1}" ]; then
+      echo "Error: more parameters expected for runtest; please see usage for details"
+      cmd="help"
+      break
+    fi
+    jar=${1}
+    if [ "${1:0:1}" = "-" ]; then
+      # we are done with jars, starting with parameters now
+      break
+    fi
+    # if relative path, append the default path prefix
+    if [ "${1:0:1}" != "/" ]; then
+      jar=${run_base}/${1}
+    fi
+    # about to add the file to class path, check if it's valid
+    if [ ! -f ${jar} ]; then
+      echo "Error: ${jar} does not exist"
+      # force to print help message
+      cmd="help"
+      break
+    fi
+    jars=${jars}:${jar}
+    # done processing current arg, moving on
+    shift
+  done
+  # look for --nohup: if found, consume it and trap SIG_HUP, otherwise just
+  # append the arg to args
+  while [ -n "${1}" ]; do
+    if [ "${1}" = "--nohup" ]; then
+      trap "" HUP
+      shift
+    else
+      args="${args} ${1}"
+      shift
+    fi
+  done
+else
+  # if cmd is not 'runtest', just take the rest of the args
+  args=${@}
+fi
+
+args="${cmd} ${args}"
+if [ -n "${jars}" ]; then
+   args="${args} -e jars ${jars}"
+fi
+
+CLASSPATH=${CLASSPATH}:${jars}
+export CLASSPATH
+exec app_process ${base}/bin com.android.commands.uiautomator.Launcher ${args}
diff --git a/instrumentation/Android.mk b/instrumentation/Android.mk
new file mode 100644
index 0000000..0c93b4c
--- /dev/null
+++ b/instrumentation/Android.mk
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2012 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SRC_FILES := $(call all-java-files-under, testrunner-src) \
+    $(call all-java-files-under, ../library/core-src)
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_MODULE := uiautomator-instrumentation
+# TODO: change this to 18 when it's available
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/instrumentation/testrunner-src/com/android/uiautomator/core/InstrumentationUiAutomatorBridge.java b/instrumentation/testrunner-src/com/android/uiautomator/core/InstrumentationUiAutomatorBridge.java
new file mode 100644
index 0000000..1d4fb93
--- /dev/null
+++ b/instrumentation/testrunner-src/com/android/uiautomator/core/InstrumentationUiAutomatorBridge.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.core;
+
+import android.app.Service;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.os.PowerManager;
+import android.view.Display;
+import android.view.ViewConfiguration;
+import android.view.WindowManager;
+
+/**
+ * @hide
+ */
+public class InstrumentationUiAutomatorBridge extends UiAutomatorBridge {
+
+    private final Context mContext;
+
+    public InstrumentationUiAutomatorBridge(Context context, UiAutomation uiAutomation) {
+        super(uiAutomation);
+        mContext = context;
+    }
+
+    public Display getDefaultDisplay() {
+        WindowManager windowManager = (WindowManager)
+                mContext.getSystemService(Service.WINDOW_SERVICE);
+        return windowManager.getDefaultDisplay();
+    }
+
+    @Override
+    public int getRotation() {
+        return getDefaultDisplay().getRotation();
+    }
+
+    @Override
+    public boolean isScreenOn() {
+        PowerManager pm = (PowerManager)
+                mContext.getSystemService(Service.POWER_SERVICE);
+        return pm.isScreenOn();
+    }
+
+    public long getSystemLongPressTime() {
+        return ViewConfiguration.getLongPressTimeout();
+    }
+}
diff --git a/instrumentation/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java b/instrumentation/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java
new file mode 100644
index 0000000..f0c60d2
--- /dev/null
+++ b/instrumentation/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.testrunner;
+
+import android.os.Bundle;
+
+/**
+ * Provides auxiliary support for running test cases
+ *
+ * @since API Level 16
+ */
+public interface IAutomationSupport {
+
+    /**
+     * Allows the running test cases to send out interim status
+     *
+     * @param resultCode
+     * @param status status report, consisting of key value pairs
+     * @since API Level 16
+     */
+    public void sendStatus(int resultCode, Bundle status);
+
+}
diff --git a/instrumentation/testrunner-src/com/android/uiautomator/testrunner/InstrumentationAutomationSupport.java b/instrumentation/testrunner-src/com/android/uiautomator/testrunner/InstrumentationAutomationSupport.java
new file mode 100644
index 0000000..a70586e
--- /dev/null
+++ b/instrumentation/testrunner-src/com/android/uiautomator/testrunner/InstrumentationAutomationSupport.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.testrunner;
+
+import android.app.Instrumentation;
+import android.os.Bundle;
+
+/**
+ * A wrapper around {@link Instrumentation} to provide sendStatus function
+ *
+ * Provided for backwards compatibility purpose. New code should use
+ * {@link Instrumentation#sendStatus(int, Bundle)} instead.
+ *
+ */
+class InstrumentationAutomationSupport implements IAutomationSupport {
+
+    private Instrumentation mInstrumentation;
+
+    InstrumentationAutomationSupport(Instrumentation instrumentation) {
+        mInstrumentation = instrumentation;
+    }
+
+    @Override
+    public void sendStatus(int resultCode, Bundle status) {
+        mInstrumentation.sendStatus(resultCode, status);
+    }
+}
diff --git a/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorInstrumentationTestRunner.java b/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorInstrumentationTestRunner.java
new file mode 100644
index 0000000..ae763f2
--- /dev/null
+++ b/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorInstrumentationTestRunner.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.testrunner;
+
+import android.test.AndroidTestRunner;
+import android.test.InstrumentationTestRunner;
+
+import com.android.uiautomator.core.Tracer;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestListener;
+
+/**
+ * Test runner for {@link UiAutomatorTestCase}s. Such tests are executed
+ * on the device and have access to an applications context.
+ */
+public class UiAutomatorInstrumentationTestRunner extends InstrumentationTestRunner {
+
+    @Override
+    public void onStart() {
+        // process runner arguments before test starts
+        String traceType = getArguments().getString("traceOutputMode");
+        if(traceType != null) {
+            Tracer.Mode mode = Tracer.Mode.valueOf(Tracer.Mode.class, traceType);
+            if (mode == Tracer.Mode.FILE || mode == Tracer.Mode.ALL) {
+                String filename = getArguments().getString("traceLogFilename");
+                if (filename == null) {
+                    throw new RuntimeException("Name of log file not specified. " +
+                            "Please specify it using traceLogFilename parameter");
+                }
+                Tracer.getInstance().setOutputFilename(filename);
+            }
+            Tracer.getInstance().setOutputMode(mode);
+        }
+        super.onStart();
+    }
+
+    @Override
+    protected AndroidTestRunner getAndroidTestRunner() {
+        AndroidTestRunner testRunner = super.getAndroidTestRunner();
+        testRunner.addTestListener(new TestListener() {
+            @Override
+            public void startTest(Test test) {
+                if (test instanceof UiAutomatorTestCase) {
+                    ((UiAutomatorTestCase)test).initialize(getArguments());
+                }
+            }
+
+            @Override
+            public void endTest(Test test) {
+            }
+
+            @Override
+            public void addFailure(Test test, AssertionFailedError e) {
+            }
+
+            @Override
+            public void addError(Test test, Throwable t) {
+            }
+        });
+        return testRunner;
+    }
+}
diff --git a/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java b/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
new file mode 100644
index 0000000..b5f21c9
--- /dev/null
+++ b/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.testrunner;
+
+import android.app.Instrumentation;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.test.InstrumentationTestCase;
+
+import com.android.uiautomator.core.InstrumentationUiAutomatorBridge;
+import com.android.uiautomator.core.UiDevice;
+
+/**
+ * UI Automator test case that is executed on the device.
+ */
+public class UiAutomatorTestCase extends InstrumentationTestCase {
+
+    private Bundle mParams;
+    private IAutomationSupport mAutomationSupport;
+
+    /**
+     * Get current instance of {@link UiDevice}. Works similar to calling the static
+     * {@link UiDevice#getInstance()} from anywhere in the test classes.
+     * @since API Level 16
+     */
+    public UiDevice getUiDevice() {
+        return UiDevice.getInstance();
+    }
+
+    /**
+     * Get command line parameters. On the command line when passing <code>-e key value</code>
+     * pairs, the {@link Bundle} will have the key value pairs conveniently available to the
+     * tests.
+     * @since API Level 16
+     */
+    public Bundle getParams() {
+        return mParams;
+    }
+
+    void setAutomationSupport(IAutomationSupport automationSupport) {
+        mAutomationSupport = automationSupport;
+    }
+
+    /**
+     * Provides support for running tests to report interim status
+     *
+     * @return IAutomationSupport
+     * @since API Level 16
+     * @deprecated Use {@link Instrumentation#sendStatus(int, Bundle)} instead
+     */
+    public IAutomationSupport getAutomationSupport() {
+        if (mAutomationSupport == null) {
+            mAutomationSupport = new InstrumentationAutomationSupport(getInstrumentation());
+        }
+        return mAutomationSupport;
+    }
+
+    /**
+     * Initializes this test case.
+     *
+     * @param params Instrumentation arguments.
+     */
+    void initialize(Bundle params) {
+        mParams = params;
+
+        // check if this is a monkey test mode
+        String monkeyVal = mParams.getString("monkey");
+        if (monkeyVal != null) {
+            // only if the monkey key is specified, we alter the state of monkey
+            // else we should leave things as they are.
+            getInstrumentation().getUiAutomation().setRunAsMonkey(Boolean.valueOf(monkeyVal));
+        }
+
+        UiDevice.getInstance().initialize(new InstrumentationUiAutomatorBridge(
+                getInstrumentation().getContext(),
+                getInstrumentation().getUiAutomation()));
+    }
+
+    /**
+     * Calls {@link SystemClock#sleep(long)} to sleep
+     * @param ms is in milliseconds.
+     * @since API Level 16
+     */
+    public void sleep(long ms) {
+        SystemClock.sleep(ms);
+    }
+}
diff --git a/library/Android.mk b/library/Android.mk
new file mode 100644
index 0000000..470e8ab
--- /dev/null
+++ b/library/Android.mk
@@ -0,0 +1,123 @@
+#
+# Copyright (C) 2012 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+uiautomator.core_src_files := $(call all-java-files-under, core-src) \
+	$(call all-java-files-under, testrunner-src)
+uiautomator.core_java_libraries := android.test.runner core-junit
+
+uiautomator_internal_api_file := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/uiautomator_api.txt
+
+###############################################
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(uiautomator.core_src_files)
+LOCAL_MODULE := uiautomator.core
+LOCAL_JAVA_LIBRARIES := android.test.runner
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+###############################################
+# Generate the stub source files
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(uiautomator.core_src_files)
+LOCAL_JAVA_LIBRARIES := $(uiautomator.core_java_libraries)
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_DROIDDOC_SOURCE_PATH := $(LOCAL_PATH)/core-src \
+	$(LOCAL_PATH)/testrunner-src
+LOCAL_DROIDDOC_HTML_DIR :=
+
+LOCAL_DROIDDOC_OPTIONS:= \
+    -stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_uiautomator_intermediates/src \
+    -stubpackages com.android.uiautomator.core:com.android.uiautomator.testrunner \
+    -api $(uiautomator_internal_api_file)
+
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := build/tools/droiddoc/templates-sdk
+LOCAL_UNINSTALLABLE_MODULE := true
+
+LOCAL_MODULE := uiautomator-stubs
+
+include $(BUILD_DROIDDOC)
+uiautomator_stubs_stamp := $(full_target)
+$(uiautomator_internal_api_file) : $(full_target)
+
+###############################################
+# Build the stub source files into a jar.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android_uiautomator
+LOCAL_JAVA_LIBRARIES := $(uiautomator.core_java_libraries)
+LOCAL_SOURCE_FILES_ALL_GENERATED := true
+include $(BUILD_STATIC_JAVA_LIBRARY)
+# Make sure to run droiddoc first to generate the stub source files.
+$(full_classes_compiled_jar) : $(uiautomator_stubs_stamp)
+uiautomator_stubs_jar := $(full_classes_compiled_jar)
+
+###############################################
+# API check
+# Please refer to build/core/tasks/apicheck.mk.
+uiautomator_api_dir := frameworks/testing/uiautomator/api
+last_released_sdk_version := $(lastword $(call numerically_sort, \
+    $(filter-out current, \
+        $(patsubst $(uiautomator_api_dir)/%.txt,%, $(wildcard $(uiautomator_api_dir)/*.txt)) \
+    )))
+
+checkapi_last_error_level_flags := \
+    -hide 2 -hide 3 -hide 4 -hide 5 -hide 6 -hide 24 -hide 25 \
+    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
+    -error 16 -error 17 -error 18
+
+# Check that the API we're building hasn't broken the last-released SDK version.
+$(eval $(call check-api, \
+    uiautomator-checkapi-last, \
+    $(uiautomator_api_dir)/$(last_released_sdk_version).txt, \
+    $(uiautomator_internal_api_file), \
+    $(checkapi_last_error_level_flags), \
+    cat $(LOCAL_PATH)/apicheck_msg_last.txt, \
+    $(uiautomator_stubs_jar), \
+    $(uiautomator_stubs_stamp)))
+
+checkapi_current_error_level_flags := \
+    -error 2 -error 3 -error 4 -error 5 -error 6 \
+    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
+    -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
+    -error 25
+
+# Check that the API we're building hasn't changed from the not-yet-released
+# SDK version.
+$(eval $(call check-api, \
+    uiautomator-checkapi-current, \
+    $(uiautomator_api_dir)/current.txt, \
+    $(uiautomator_internal_api_file), \
+    $(checkapi_current_error_level_flags), \
+    cat $(LOCAL_PATH)/apicheck_msg_current.txt, \
+    $(uiautomator_stubs_jar), \
+    $(uiautomator_stubs_stamp)))
+
+.PHONY: update-uiautomator-api
+update-uiautomator-api: PRIVATE_API_DIR := $(uiautomator_api_dir)
+update-uiautomator-api: $(uiautomator_internal_api_file) | $(ACP)
+	@echo Copying uiautomator current.txt
+	$(hide) $(ACP) $< $(PRIVATE_API_DIR)/current.txt
+
+###############################################
+# clean up temp vars
+uiautomator.core_src_files :=
+uiautomator.core_java_libraries :=
+uiautomator_stubs_stamp :=
+uiautomator_internal_api_file :=
+uiautomator_stubs_jar :=
+uiautomator_api_dir :=
+checkapi_last_error_level_flags :=
+checkapi_current_error_level_flags :=
diff --git a/library/apicheck_msg_current.txt b/library/apicheck_msg_current.txt
new file mode 100644
index 0000000..989248d
--- /dev/null
+++ b/library/apicheck_msg_current.txt
@@ -0,0 +1,17 @@
+
+******************************
+You have tried to change the API from what has been previously approved.
+
+To make these errors go away, you have two choices:
+   1) You can add "@hide" javadoc comments to the methods, etc. listed in the
+      errors above.
+
+   2) You can update current.txt by executing the following command:
+         make update-uiautomator-api
+
+      To submit the revised current.txt to the main Android repository,
+      you will need approval.
+******************************
+
+
+
diff --git a/library/apicheck_msg_last.txt b/library/apicheck_msg_last.txt
new file mode 100644
index 0000000..2993157
--- /dev/null
+++ b/library/apicheck_msg_last.txt
@@ -0,0 +1,7 @@
+
+******************************
+You have tried to change the API from what has been previously released in
+an SDK.  Please fix the errors listed above.
+******************************
+
+
diff --git a/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java b/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
new file mode 100644
index 0000000..63c51e8
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+import android.os.Environment;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.Xml;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+
+/**
+ *
+ * @hide
+ */
+public class AccessibilityNodeInfoDumper {
+
+    private static final String LOGTAG = AccessibilityNodeInfoDumper.class.getSimpleName();
+    private static final String[] NAF_EXCLUDED_CLASSES = new String[] {
+            android.widget.GridView.class.getName(), android.widget.GridLayout.class.getName(),
+            android.widget.ListView.class.getName(), android.widget.TableLayout.class.getName()
+    };
+
+    /**
+     * Using {@link AccessibilityNodeInfo} this method will walk the layout hierarchy
+     * and generates an xml dump into the /data/local/window_dump.xml
+     * @param root The root accessibility node.
+     * @param rotation The rotaion of current display
+     * @param width The pixel width of current display
+     * @param height The pixel height of current display
+     */
+    public static void dumpWindowToFile(AccessibilityNodeInfo root, int rotation,
+            int width, int height) {
+        File baseDir = new File(Environment.getDataDirectory(), "local");
+        if (!baseDir.exists()) {
+            baseDir.mkdir();
+            baseDir.setExecutable(true, false);
+            baseDir.setWritable(true, false);
+            baseDir.setReadable(true, false);
+        }
+        dumpWindowToFile(root,
+                new File(new File(Environment.getDataDirectory(), "local"), "window_dump.xml"),
+                rotation, width, height);
+    }
+
+    /**
+     * Using {@link AccessibilityNodeInfo} this method will walk the layout hierarchy
+     * and generates an xml dump to the location specified by <code>dumpFile</code>
+     * @param root The root accessibility node.
+     * @param dumpFile The file to dump to.
+     * @param rotation The rotaion of current display
+     * @param width The pixel width of current display
+     * @param height The pixel height of current display
+     */
+    public static void dumpWindowToFile(AccessibilityNodeInfo root, File dumpFile, int rotation,
+            int width, int height) {
+        if (root == null) {
+            return;
+        }
+        final long startTime = SystemClock.uptimeMillis();
+        try {
+            FileWriter writer = new FileWriter(dumpFile);
+            XmlSerializer serializer = Xml.newSerializer();
+            StringWriter stringWriter = new StringWriter();
+            serializer.setOutput(stringWriter);
+            serializer.startDocument("UTF-8", true);
+            serializer.startTag("", "hierarchy");
+            serializer.attribute("", "rotation", Integer.toString(rotation));
+            dumpNodeRec(root, serializer, 0, width, height);
+            serializer.endTag("", "hierarchy");
+            serializer.endDocument();
+            writer.write(stringWriter.toString());
+            writer.close();
+        } catch (IOException e) {
+            Log.e(LOGTAG, "failed to dump window to file", e);
+        }
+        final long endTime = SystemClock.uptimeMillis();
+        Log.w(LOGTAG, "Fetch time: " + (endTime - startTime) + "ms");
+    }
+
+    private static void dumpNodeRec(AccessibilityNodeInfo node, XmlSerializer serializer,int index,
+            int width, int height) throws IOException {
+        serializer.startTag("", "node");
+        if (!nafExcludedClass(node) && !nafCheck(node))
+            serializer.attribute("", "NAF", Boolean.toString(true));
+        serializer.attribute("", "index", Integer.toString(index));
+        serializer.attribute("", "text", safeCharSeqToString(node.getText()));
+        serializer.attribute("", "resource-id", safeCharSeqToString(node.getViewIdResourceName()));
+        serializer.attribute("", "class", safeCharSeqToString(node.getClassName()));
+        serializer.attribute("", "package", safeCharSeqToString(node.getPackageName()));
+        serializer.attribute("", "content-desc", safeCharSeqToString(node.getContentDescription()));
+        serializer.attribute("", "checkable", Boolean.toString(node.isCheckable()));
+        serializer.attribute("", "checked", Boolean.toString(node.isChecked()));
+        serializer.attribute("", "clickable", Boolean.toString(node.isClickable()));
+        serializer.attribute("", "enabled", Boolean.toString(node.isEnabled()));
+        serializer.attribute("", "focusable", Boolean.toString(node.isFocusable()));
+        serializer.attribute("", "focused", Boolean.toString(node.isFocused()));
+        serializer.attribute("", "scrollable", Boolean.toString(node.isScrollable()));
+        serializer.attribute("", "long-clickable", Boolean.toString(node.isLongClickable()));
+        serializer.attribute("", "password", Boolean.toString(node.isPassword()));
+        serializer.attribute("", "selected", Boolean.toString(node.isSelected()));
+        serializer.attribute("", "bounds", AccessibilityNodeInfoHelper.getVisibleBoundsInScreen(
+                node, width, height).toShortString());
+        int count = node.getChildCount();
+        for (int i = 0; i < count; i++) {
+            AccessibilityNodeInfo child = node.getChild(i);
+            if (child != null) {
+                if (child.isVisibleToUser()) {
+                    dumpNodeRec(child, serializer, i, width, height);
+                    child.recycle();
+                } else {
+                    Log.i(LOGTAG, String.format("Skipping invisible child: %s", child.toString()));
+                }
+            } else {
+                Log.i(LOGTAG, String.format("Null child %d/%d, parent: %s",
+                        i, count, node.toString()));
+            }
+        }
+        serializer.endTag("", "node");
+    }
+
+    /**
+     * The list of classes to exclude my not be complete. We're attempting to
+     * only reduce noise from standard layout classes that may be falsely
+     * configured to accept clicks and are also enabled.
+     *
+     * @param node
+     * @return true if node is excluded.
+     */
+    private static boolean nafExcludedClass(AccessibilityNodeInfo node) {
+        String className = safeCharSeqToString(node.getClassName());
+        for(String excludedClassName : NAF_EXCLUDED_CLASSES) {
+            if(className.endsWith(excludedClassName))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * We're looking for UI controls that are enabled, clickable but have no
+     * text nor content-description. Such controls configuration indicate an
+     * interactive control is present in the UI and is most likely not
+     * accessibility friendly. We refer to such controls here as NAF controls
+     * (Not Accessibility Friendly)
+     *
+     * @param node
+     * @return false if a node fails the check, true if all is OK
+     */
+    private static boolean nafCheck(AccessibilityNodeInfo node) {
+        boolean isNaf = node.isClickable() && node.isEnabled()
+                && safeCharSeqToString(node.getContentDescription()).isEmpty()
+                && safeCharSeqToString(node.getText()).isEmpty();
+
+        if (!isNaf)
+            return true;
+
+        // check children since sometimes the containing element is clickable
+        // and NAF but a child's text or description is available. Will assume
+        // such layout as fine.
+        return childNafCheck(node);
+    }
+
+    /**
+     * This should be used when it's already determined that the node is NAF and
+     * a further check of its children is in order. A node maybe a container
+     * such as LinerLayout and may be set to be clickable but have no text or
+     * content description but it is counting on one of its children to fulfill
+     * the requirement for being accessibility friendly by having one or more of
+     * its children fill the text or content-description. Such a combination is
+     * considered by this dumper as acceptable for accessibility.
+     *
+     * @param node
+     * @return false if node fails the check.
+     */
+    private static boolean childNafCheck(AccessibilityNodeInfo node) {
+        int childCount = node.getChildCount();
+        for (int x = 0; x < childCount; x++) {
+            AccessibilityNodeInfo childNode = node.getChild(x);
+
+            if (!safeCharSeqToString(childNode.getContentDescription()).isEmpty()
+                    || !safeCharSeqToString(childNode.getText()).isEmpty())
+                return true;
+
+            if (childNafCheck(childNode))
+                return true;
+        }
+        return false;
+    }
+
+    private static String safeCharSeqToString(CharSequence cs) {
+        if (cs == null)
+            return "";
+        else {
+            return stripInvalidXMLChars(cs);
+        }
+    }
+
+    private static String stripInvalidXMLChars(CharSequence cs) {
+        StringBuffer ret = new StringBuffer();
+        char ch;
+        /* http://www.w3.org/TR/xml11/#charsets
+        [#x1-#x8], [#xB-#xC], [#xE-#x1F], [#x7F-#x84], [#x86-#x9F], [#xFDD0-#xFDDF],
+        [#x1FFFE-#x1FFFF], [#x2FFFE-#x2FFFF], [#x3FFFE-#x3FFFF],
+        [#x4FFFE-#x4FFFF], [#x5FFFE-#x5FFFF], [#x6FFFE-#x6FFFF],
+        [#x7FFFE-#x7FFFF], [#x8FFFE-#x8FFFF], [#x9FFFE-#x9FFFF],
+        [#xAFFFE-#xAFFFF], [#xBFFFE-#xBFFFF], [#xCFFFE-#xCFFFF],
+        [#xDFFFE-#xDFFFF], [#xEFFFE-#xEFFFF], [#xFFFFE-#xFFFFF],
+        [#x10FFFE-#x10FFFF].
+         */
+        for (int i = 0; i < cs.length(); i++) {
+            ch = cs.charAt(i);
+
+            if((ch >= 0x1 && ch <= 0x8) || (ch >= 0xB && ch <= 0xC) || (ch >= 0xE && ch <= 0x1F) ||
+                    (ch >= 0x7F && ch <= 0x84) || (ch >= 0x86 && ch <= 0x9f) ||
+                    (ch >= 0xFDD0 && ch <= 0xFDDF) || (ch >= 0x1FFFE && ch <= 0x1FFFF) ||
+                    (ch >= 0x2FFFE && ch <= 0x2FFFF) || (ch >= 0x3FFFE && ch <= 0x3FFFF) ||
+                    (ch >= 0x4FFFE && ch <= 0x4FFFF) || (ch >= 0x5FFFE && ch <= 0x5FFFF) ||
+                    (ch >= 0x6FFFE && ch <= 0x6FFFF) || (ch >= 0x7FFFE && ch <= 0x7FFFF) ||
+                    (ch >= 0x8FFFE && ch <= 0x8FFFF) || (ch >= 0x9FFFE && ch <= 0x9FFFF) ||
+                    (ch >= 0xAFFFE && ch <= 0xAFFFF) || (ch >= 0xBFFFE && ch <= 0xBFFFF) ||
+                    (ch >= 0xCFFFE && ch <= 0xCFFFF) || (ch >= 0xDFFFE && ch <= 0xDFFFF) ||
+                    (ch >= 0xEFFFE && ch <= 0xEFFFF) || (ch >= 0xFFFFE && ch <= 0xFFFFF) ||
+                    (ch >= 0x10FFFE && ch <= 0x10FFFF))
+                ret.append(".");
+            else
+                ret.append(ch);
+        }
+        return ret.toString();
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoHelper.java b/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoHelper.java
new file mode 100644
index 0000000..54835e3
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoHelper.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+import android.graphics.Rect;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+/**
+ * This class contains static helper methods to work with
+ * {@link AccessibilityNodeInfo}
+ */
+class AccessibilityNodeInfoHelper {
+
+    /**
+     * Returns the node's bounds clipped to the size of the display
+     *
+     * @param node
+     * @param width pixel width of the display
+     * @param height pixel height of the display
+     * @return null if node is null, else a Rect containing visible bounds
+     */
+    static Rect getVisibleBoundsInScreen(AccessibilityNodeInfo node, int width, int height) {
+        if (node == null) {
+            return null;
+        }
+        // targeted node's bounds
+        Rect nodeRect = new Rect();
+        node.getBoundsInScreen(nodeRect);
+
+        Rect displayRect = new Rect();
+        displayRect.top = 0;
+        displayRect.left = 0;
+        displayRect.right = width;
+        displayRect.bottom = height;
+
+        nodeRect.intersect(displayRect);
+        return nodeRect;
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/Configurator.java b/library/core-src/com/android/uiautomator/core/Configurator.java
new file mode 100644
index 0000000..249f404
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/Configurator.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.core;
+
+/**
+ * Allows you to set key parameters for running uiautomator tests. The new
+ * settings take effect immediately and can be changed any time during a test run.
+ *
+ * To modify parameters using Configurator, first obtain an instance by calling
+ * {@link #getInstance()}. As a best practice, make sure you always save
+ * the original value of any parameter that you are modifying. After running your
+ * tests with the modified parameters, make sure to also restore
+ * the original parameter values, otherwise this will impact other tests cases.
+ * @since API Level 18
+ */
+public final class Configurator {
+    private long mWaitForIdleTimeout = 10 * 1000;
+    private long mWaitForSelector = 10 * 1000;
+    private long mWaitForActionAcknowledgment = 3 * 1000;
+
+    // The events for a scroll typically complete even before touchUp occurs.
+    // This short timeout to make sure we get the very last in cases where the above isn't true.
+    private long mScrollEventWaitTimeout = 200; // ms
+
+    // Default is inject as fast as we can
+    private long mKeyInjectionDelay = 0; // ms
+
+    // reference to self
+    private static Configurator sConfigurator;
+
+    private Configurator() {
+        /* hide constructor */
+    }
+
+    /**
+     * Retrieves a singleton instance of Configurator.
+     *
+     * @return Configurator instance
+     * @since API Level 18
+     */
+    public static Configurator getInstance() {
+        if (sConfigurator == null) {
+            sConfigurator = new Configurator();
+        }
+        return sConfigurator;
+    }
+
+    /**
+     * Sets the timeout for waiting for the user interface to go into an idle
+     * state before starting a uiautomator action.
+     *
+     * By default, all core uiautomator objects except {@link UiDevice} will perform
+     * this wait before starting to search for the widget specified by the
+     * object's {@link UiSelector}. Once the idle state is detected or the
+     * timeout elapses (whichever occurs first), the object will start to wait
+     * for the selector to find a match.
+     * See {@link #setWaitForSelectorTimeout(long)}
+     *
+     * @param timeout Timeout value in milliseconds
+     * @return self
+     * @since API Level 18
+     */
+    public Configurator setWaitForIdleTimeout(long timeout) {
+        mWaitForIdleTimeout = timeout;
+        return this;
+    }
+
+    /**
+     * Gets the current timeout used for waiting for the user interface to go
+     * into an idle state.
+     *
+     * By default, all core uiautomator objects except {@link UiDevice} will perform
+     * this wait before starting to search for the widget specified by the
+     * object's {@link UiSelector}. Once the idle state is detected or the
+     * timeout elapses (whichever occurs first), the object will start to wait
+     * for the selector to find a match.
+     * See {@link #setWaitForSelectorTimeout(long)}
+     *
+     * @return Current timeout value in milliseconds
+     * @since API Level 18
+     */
+    public long getWaitForIdleTimeout() {
+        return mWaitForIdleTimeout;
+    }
+
+    /**
+     * Sets the timeout for waiting for a widget to become visible in the user
+     * interface so that it can be matched by a selector.
+     *
+     * Because user interface content is dynamic, sometimes a widget may not
+     * be visible immediately and won't be detected by a selector. This timeout
+     * allows the uiautomator framework to wait for a match to be found, up until
+     * the timeout elapses.
+     *
+     * @param timeout Timeout value in milliseconds.
+     * @return self
+     * @since API Level 18
+     */
+    public Configurator setWaitForSelectorTimeout(long timeout) {
+        mWaitForSelector = timeout;
+        return this;
+    }
+
+    /**
+     * Gets the current timeout for waiting for a widget to become visible in
+     * the user interface so that it can be matched by a selector.
+     *
+     * Because user interface content is dynamic, sometimes a widget may not
+     * be visible immediately and won't be detected by a selector. This timeout
+     * allows the uiautomator framework to wait for a match to be found, up until
+     * the timeout elapses.
+     *
+     * @return Current timeout value in milliseconds
+     * @since API Level 18
+     */
+    public long getWaitForSelectorTimeout() {
+        return mWaitForSelector;
+    }
+
+    /**
+     * Sets the timeout for waiting for an acknowledgement of an
+     * uiautomtor scroll swipe action.
+     *
+     * The acknowledgment is an <a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html">AccessibilityEvent</a>,
+     * corresponding to the scroll action, that lets the framework determine if
+     * the scroll action was successful. Generally, this timeout should not be modified.
+     * See {@link UiScrollable}
+     *
+     * @param timeout Timeout value in milliseconds
+     * @return self
+     * @since API Level 18
+     */
+    public Configurator setScrollAcknowledgmentTimeout(long timeout) {
+        mScrollEventWaitTimeout = timeout;
+        return this;
+    }
+
+    /**
+     * Gets the timeout for waiting for an acknowledgement of an
+     * uiautomtor scroll swipe action.
+     *
+     * The acknowledgment is an <a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html">AccessibilityEvent</a>,
+     * corresponding to the scroll action, that lets the framework determine if
+     * the scroll action was successful. Generally, this timeout should not be modified.
+     * See {@link UiScrollable}
+     *
+     * @return current timeout in milliseconds
+     * @since API Level 18
+     */
+    public long getScrollAcknowledgmentTimeout() {
+        return mScrollEventWaitTimeout;
+    }
+
+    /**
+     * Sets the timeout for waiting for an acknowledgment of generic uiautomator
+     * actions, such as clicks, text setting, and menu presses.
+     *
+     * The acknowledgment is an <a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html">AccessibilityEvent</a>,
+     * corresponding to an action, that lets the framework determine if the
+     * action was successful. Generally, this timeout should not be modified.
+     * See {@link UiObject}
+     *
+     * @param timeout Timeout value in milliseconds
+     * @return self
+     * @since API Level 18
+     */
+    public Configurator setActionAcknowledgmentTimeout(long timeout) {
+        mWaitForActionAcknowledgment = timeout;
+        return this;
+    }
+
+    /**
+     * Gets the current timeout for waiting for an acknowledgment of generic
+     * uiautomator actions, such as clicks, text setting, and menu presses.
+     *
+     * The acknowledgment is an <a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html">AccessibilityEvent</a>,
+     * corresponding to an action, that lets the framework determine if the
+     * action was successful. Generally, this timeout should not be modified.
+     * See {@link UiObject}
+     *
+     * @return current timeout in milliseconds
+     * @since API Level 18
+     */
+    public long getActionAcknowledgmentTimeout() {
+        return mWaitForActionAcknowledgment;
+    }
+
+    /**
+     * Sets a delay between key presses when injecting text input.
+     * See {@link UiObject#setText(String)}
+     *
+     * @param delay Delay value in milliseconds
+     * @return self
+     * @since API Level 18
+     */
+    public Configurator setKeyInjectionDelay(long delay) {
+        mKeyInjectionDelay = delay;
+        return this;
+    }
+
+    /**
+     * Gets the current delay between key presses when injecting text input.
+     * See {@link UiObject#setText(String)}
+     *
+     * @return current delay in milliseconds
+     * @since API Level 18
+     */
+    public long getKeyInjectionDelay() {
+        return mKeyInjectionDelay;
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/InteractionController.java b/library/core-src/com/android/uiautomator/core/InteractionController.java
new file mode 100644
index 0000000..73e46f1
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/InteractionController.java
@@ -0,0 +1,795 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+import android.accessibilityservice.AccessibilityService;
+import android.app.UiAutomation;
+import android.app.UiAutomation.AccessibilityEventFilter;
+import android.graphics.Point;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.MotionEvent.PointerCoords;
+import android.view.MotionEvent.PointerProperties;
+import android.view.accessibility.AccessibilityEvent;
+
+import com.android.internal.util.Predicate;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * The InteractionProvider is responsible for injecting user events such as touch events
+ * (includes swipes) and text key events into the system. To do so, all it needs to know about
+ * are coordinates of the touch events and text for the text input events.
+ * The InteractionController performs no synchronization. It will fire touch and text input events
+ * as fast as it receives them. All idle synchronization is performed prior to querying the
+ * hierarchy. See {@link QueryController}
+ */
+class InteractionController {
+
+    private static final String LOG_TAG = InteractionController.class.getSimpleName();
+
+    private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
+
+    private final KeyCharacterMap mKeyCharacterMap =
+            KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
+
+    private final UiAutomatorBridge mUiAutomatorBridge;
+
+    private static final long REGULAR_CLICK_LENGTH = 100;
+
+    private long mDownTime;
+
+    // Inserted after each motion event injection.
+    private static final int MOTION_EVENT_INJECTION_DELAY_MILLIS = 5;
+
+    public InteractionController(UiAutomatorBridge bridge) {
+        mUiAutomatorBridge = bridge;
+    }
+
+    /**
+     * Predicate for waiting for any of the events specified in the mask
+     */
+    class WaitForAnyEventPredicate implements AccessibilityEventFilter {
+        int mMask;
+        WaitForAnyEventPredicate(int mask) {
+            mMask = mask;
+        }
+        @Override
+        public boolean accept(AccessibilityEvent t) {
+            // check current event in the list
+            if ((t.getEventType() & mMask) != 0) {
+                return true;
+            }
+
+            // no match yet
+            return false;
+        }
+    }
+
+    /**
+     * Predicate for waiting for all the events specified in the mask and populating
+     * a ctor passed list with matching events. User of this Predicate must recycle
+     * all populated events in the events list.
+     */
+    class EventCollectingPredicate implements AccessibilityEventFilter {
+        int mMask;
+        List<AccessibilityEvent> mEventsList;
+
+        EventCollectingPredicate(int mask, List<AccessibilityEvent> events) {
+            mMask = mask;
+            mEventsList = events;
+        }
+
+        @Override
+        public boolean accept(AccessibilityEvent t) {
+            // check current event in the list
+            if ((t.getEventType() & mMask) != 0) {
+                // For the events you need, always store a copy when returning false from
+                // predicates since the original will automatically be recycled after the call.
+                mEventsList.add(AccessibilityEvent.obtain(t));
+            }
+
+            // get more
+            return false;
+        }
+    }
+
+    /**
+     * Predicate for waiting for every event specified in the mask to be matched at least once
+     */
+    class WaitForAllEventPredicate implements AccessibilityEventFilter {
+        int mMask;
+        WaitForAllEventPredicate(int mask) {
+            mMask = mask;
+        }
+
+        @Override
+        public boolean accept(AccessibilityEvent t) {
+            // check current event in the list
+            if ((t.getEventType() & mMask) != 0) {
+                // remove from mask since this condition is satisfied
+                mMask &= ~t.getEventType();
+
+                // Since we're waiting for all events to be matched at least once
+                if (mMask != 0)
+                    return false;
+
+                // all matched
+                return true;
+            }
+
+            // no match yet
+            return false;
+        }
+    }
+
+    /**
+     * Helper used by methods to perform actions and wait for any accessibility events and return
+     * predicated on predefined filter.
+     *
+     * @param command
+     * @param filter
+     * @param timeout
+     * @return
+     */
+    private AccessibilityEvent runAndWaitForEvents(Runnable command,
+            AccessibilityEventFilter filter, long timeout) {
+
+        try {
+            return mUiAutomatorBridge.executeCommandAndWaitForAccessibilityEvent(command, filter,
+                    timeout);
+        } catch (TimeoutException e) {
+            Log.w(LOG_TAG, "runAndwaitForEvent timedout waiting for events");
+            return null;
+        } catch (Exception e) {
+            Log.e(LOG_TAG, "exception from executeCommandAndWaitForAccessibilityEvent", e);
+            return null;
+        }
+    }
+
+    /**
+     * Send keys and blocks until the first specified accessibility event.
+     *
+     * Most key presses will cause some UI change to occur. If the device is busy, this will
+     * block until the device begins to process the key press at which point the call returns
+     * and normal wait for idle processing may begin. If no events are detected for the
+     * timeout period specified, the call will return anyway with false.
+     *
+     * @param keyCode
+     * @param metaState
+     * @param eventType
+     * @param timeout
+     * @return true if events is received, otherwise false.
+     */
+    public boolean sendKeyAndWaitForEvent(final int keyCode, final int metaState,
+            final int eventType, long timeout) {
+        Runnable command = new Runnable() {
+            @Override
+            public void run() {
+                final long eventTime = SystemClock.uptimeMillis();
+                KeyEvent downEvent = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN,
+                        keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
+                        InputDevice.SOURCE_KEYBOARD);
+                if (injectEventSync(downEvent)) {
+                    KeyEvent upEvent = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_UP,
+                            keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
+                            InputDevice.SOURCE_KEYBOARD);
+                    injectEventSync(upEvent);
+                }
+            }
+        };
+
+        return runAndWaitForEvents(command, new WaitForAnyEventPredicate(eventType), timeout)
+                != null;
+    }
+
+    /**
+     * Clicks at coordinates without waiting for device idle. This may be used for operations
+     * that require stressing the target.
+     * @param x
+     * @param y
+     * @return true if the click executed successfully
+     */
+    public boolean clickNoSync(int x, int y) {
+        Log.d(LOG_TAG, "clickNoSync (" + x + ", " + y + ")");
+
+        if (touchDown(x, y)) {
+            SystemClock.sleep(REGULAR_CLICK_LENGTH);
+            if (touchUp(x, y))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Click at coordinates and blocks until either accessibility event TYPE_WINDOW_CONTENT_CHANGED
+     * or TYPE_VIEW_SELECTED are received.
+     *
+     * @param x
+     * @param y
+     * @param timeout waiting for event
+     * @return true if events are received, else false if timeout.
+     */
+    public boolean clickAndSync(final int x, final int y, long timeout) {
+
+        String logString = String.format("clickAndSync(%d, %d)", x, y);
+        Log.d(LOG_TAG, logString);
+
+        return runAndWaitForEvents(clickRunnable(x, y), new WaitForAnyEventPredicate(
+                AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED |
+                AccessibilityEvent.TYPE_VIEW_SELECTED), timeout) != null;
+    }
+
+    /**
+     * Clicks at coordinates and waits for for a TYPE_WINDOW_STATE_CHANGED event followed
+     * by TYPE_WINDOW_CONTENT_CHANGED. If timeout occurs waiting for TYPE_WINDOW_STATE_CHANGED,
+     * no further waits will be performed and the function returns.
+     * @param x
+     * @param y
+     * @param timeout waiting for event
+     * @return true if both events occurred in the expected order
+     */
+    public boolean clickAndWaitForNewWindow(final int x, final int y, long timeout) {
+        String logString = String.format("clickAndWaitForNewWindow(%d, %d)", x, y);
+        Log.d(LOG_TAG, logString);
+
+        return runAndWaitForEvents(clickRunnable(x, y), new WaitForAllEventPredicate(
+                AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED |
+                AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED), timeout) != null;
+    }
+
+    /**
+     * Returns a Runnable for use in {@link #runAndWaitForEvents(Runnable, Predicate, long) to
+     * perform a click.
+     *
+     * @param x coordinate
+     * @param y coordinate
+     * @return Runnable
+     */
+    private Runnable clickRunnable(final int x, final int y) {
+        return new Runnable() {
+            @Override
+            public void run() {
+                if(touchDown(x, y)) {
+                    SystemClock.sleep(REGULAR_CLICK_LENGTH);
+                    touchUp(x, y);
+                }
+            }
+        };
+    }
+
+    /**
+     * Touches down for a long press at the specified coordinates.
+     *
+     * @param x
+     * @param y
+     * @return true if successful.
+     */
+    public boolean longTapNoSync(int x, int y) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "longTapNoSync (" + x + ", " + y + ")");
+        }
+
+        if (touchDown(x, y)) {
+            SystemClock.sleep(mUiAutomatorBridge.getSystemLongPressTime());
+            if(touchUp(x, y)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean touchDown(int x, int y) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "touchDown (" + x + ", " + y + ")");
+        }
+        mDownTime = SystemClock.uptimeMillis();
+        MotionEvent event = MotionEvent.obtain(
+                mDownTime, mDownTime, MotionEvent.ACTION_DOWN, x, y, 1);
+        event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        return injectEventSync(event);
+    }
+
+    private boolean touchUp(int x, int y) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "touchUp (" + x + ", " + y + ")");
+        }
+        final long eventTime = SystemClock.uptimeMillis();
+        MotionEvent event = MotionEvent.obtain(
+                mDownTime, eventTime, MotionEvent.ACTION_UP, x, y, 1);
+        event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        mDownTime = 0;
+        return injectEventSync(event);
+    }
+
+    private boolean touchMove(int x, int y) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "touchMove (" + x + ", " + y + ")");
+        }
+        final long eventTime = SystemClock.uptimeMillis();
+        MotionEvent event = MotionEvent.obtain(
+                mDownTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 1);
+        event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        return injectEventSync(event);
+    }
+
+    /**
+     * Handle swipes in any direction where the result is a scroll event. This call blocks
+     * until the UI has fired a scroll event or timeout.
+     * @param downX
+     * @param downY
+     * @param upX
+     * @param upY
+     * @param steps
+     * @return true if we are not at the beginning or end of the scrollable view.
+     */
+    public boolean scrollSwipe(final int downX, final int downY, final int upX, final int upY,
+            final int steps) {
+        Log.d(LOG_TAG, "scrollSwipe (" +  downX + ", " + downY + ", " + upX + ", "
+                + upY + ", " + steps +")");
+
+        Runnable command = new Runnable() {
+            @Override
+            public void run() {
+                swipe(downX, downY, upX, upY, steps);
+            }
+        };
+
+        // Collect all accessibility events generated during the swipe command and get the
+        // last event
+        ArrayList<AccessibilityEvent> events = new ArrayList<AccessibilityEvent>();
+        runAndWaitForEvents(command,
+                new EventCollectingPredicate(AccessibilityEvent.TYPE_VIEW_SCROLLED, events),
+                Configurator.getInstance().getScrollAcknowledgmentTimeout());
+
+        AccessibilityEvent event = getLastMatchingEvent(events,
+                AccessibilityEvent.TYPE_VIEW_SCROLLED);
+
+        if (event == null) {
+            // end of scroll since no new scroll events received
+            recycleAccessibilityEvents(events);
+            return false;
+        }
+
+        // AdapterViews have indices we can use to check for the beginning.
+        boolean foundEnd = false;
+        if (event.getFromIndex() != -1 && event.getToIndex() != -1 && event.getItemCount() != -1) {
+            foundEnd = event.getFromIndex() == 0 ||
+                    (event.getItemCount() - 1) == event.getToIndex();
+            Log.d(LOG_TAG, "scrollSwipe reached scroll end: " + foundEnd);
+        } else if (event.getScrollX() != -1 && event.getScrollY() != -1) {
+            // Determine if we are scrolling vertically or horizontally.
+            if (downX == upX) {
+                // Vertical
+                foundEnd = event.getScrollY() == 0 ||
+                        event.getScrollY() == event.getMaxScrollY();
+                Log.d(LOG_TAG, "Vertical scrollSwipe reached scroll end: " + foundEnd);
+            } else if (downY == upY) {
+                // Horizontal
+                foundEnd = event.getScrollX() == 0 ||
+                        event.getScrollX() == event.getMaxScrollX();
+                Log.d(LOG_TAG, "Horizontal scrollSwipe reached scroll end: " + foundEnd);
+            }
+        }
+        recycleAccessibilityEvents(events);
+        return !foundEnd;
+    }
+
+    private AccessibilityEvent getLastMatchingEvent(List<AccessibilityEvent> events, int type) {
+        for (int x = events.size(); x > 0; x--) {
+            AccessibilityEvent event = events.get(x - 1);
+            if (event.getEventType() == type)
+                return event;
+        }
+        return null;
+    }
+
+    private void recycleAccessibilityEvents(List<AccessibilityEvent> events) {
+        for (AccessibilityEvent event : events)
+            event.recycle();
+        events.clear();
+    }
+
+    /**
+     * Handle swipes in any direction.
+     * @param downX
+     * @param downY
+     * @param upX
+     * @param upY
+     * @param steps
+     * @return true if the swipe executed successfully
+     */
+    public boolean swipe(int downX, int downY, int upX, int upY, int steps) {
+        return swipe(downX, downY, upX, upY, steps, false /*drag*/);
+    }
+
+    /**
+     * Handle swipes/drags in any direction.
+     * @param downX
+     * @param downY
+     * @param upX
+     * @param upY
+     * @param steps
+     * @param drag when true, the swipe becomes a drag swipe
+     * @return true if the swipe executed successfully
+     */
+    public boolean swipe(int downX, int downY, int upX, int upY, int steps, boolean drag) {
+        boolean ret = false;
+        int swipeSteps = steps;
+        double xStep = 0;
+        double yStep = 0;
+
+        // avoid a divide by zero
+        if(swipeSteps == 0)
+            swipeSteps = 1;
+
+        xStep = ((double)(upX - downX)) / swipeSteps;
+        yStep = ((double)(upY - downY)) / swipeSteps;
+
+        // first touch starts exactly at the point requested
+        ret = touchDown(downX, downY);
+        if (drag)
+            SystemClock.sleep(mUiAutomatorBridge.getSystemLongPressTime());
+        for(int i = 1; i < swipeSteps; i++) {
+            ret &= touchMove(downX + (int)(xStep * i), downY + (int)(yStep * i));
+            if(ret == false)
+                break;
+            // set some known constant delay between steps as without it this
+            // become completely dependent on the speed of the system and results
+            // may vary on different devices. This guarantees at minimum we have
+            // a preset delay.
+            SystemClock.sleep(MOTION_EVENT_INJECTION_DELAY_MILLIS);
+        }
+        if (drag)
+            SystemClock.sleep(REGULAR_CLICK_LENGTH);
+        ret &= touchUp(upX, upY);
+        return(ret);
+    }
+
+    /**
+     * Performs a swipe between points in the Point array.
+     * @param segments is Point array containing at least one Point object
+     * @param segmentSteps steps to inject between two Points
+     * @return true on success
+     */
+    public boolean swipe(Point[] segments, int segmentSteps) {
+        boolean ret = false;
+        int swipeSteps = segmentSteps;
+        double xStep = 0;
+        double yStep = 0;
+
+        // avoid a divide by zero
+        if(segmentSteps == 0)
+            segmentSteps = 1;
+
+        // must have some points
+        if(segments.length == 0)
+            return false;
+
+        // first touch starts exactly at the point requested
+        ret = touchDown(segments[0].x, segments[0].y);
+        for(int seg = 0; seg < segments.length; seg++) {
+            if(seg + 1 < segments.length) {
+
+                xStep = ((double)(segments[seg+1].x - segments[seg].x)) / segmentSteps;
+                yStep = ((double)(segments[seg+1].y - segments[seg].y)) / segmentSteps;
+
+                for(int i = 1; i < swipeSteps; i++) {
+                    ret &= touchMove(segments[seg].x + (int)(xStep * i),
+                            segments[seg].y + (int)(yStep * i));
+                    if(ret == false)
+                        break;
+                    // set some known constant delay between steps as without it this
+                    // become completely dependent on the speed of the system and results
+                    // may vary on different devices. This guarantees at minimum we have
+                    // a preset delay.
+                    SystemClock.sleep(MOTION_EVENT_INJECTION_DELAY_MILLIS);
+                }
+            }
+        }
+        ret &= touchUp(segments[segments.length - 1].x, segments[segments.length -1].y);
+        return(ret);
+    }
+
+
+    public boolean sendText(String text) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "sendText (" + text + ")");
+        }
+
+        KeyEvent[] events = mKeyCharacterMap.getEvents(text.toCharArray());
+
+        if (events != null) {
+            long keyDelay = Configurator.getInstance().getKeyInjectionDelay();
+            for (KeyEvent event2 : events) {
+                // We have to change the time of an event before injecting it because
+                // all KeyEvents returned by KeyCharacterMap.getEvents() have the same
+                // time stamp and the system rejects too old events. Hence, it is
+                // possible for an event to become stale before it is injected if it
+                // takes too long to inject the preceding ones.
+                KeyEvent event = KeyEvent.changeTimeRepeat(event2,
+                        SystemClock.uptimeMillis(), 0);
+                if (!injectEventSync(event)) {
+                    return false;
+                }
+                SystemClock.sleep(keyDelay);
+            }
+        }
+        return true;
+    }
+
+    public boolean sendKey(int keyCode, int metaState) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "sendKey (" + keyCode + ", " + metaState + ")");
+        }
+
+        final long eventTime = SystemClock.uptimeMillis();
+        KeyEvent downEvent = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN,
+                keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
+                InputDevice.SOURCE_KEYBOARD);
+        if (injectEventSync(downEvent)) {
+            KeyEvent upEvent = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_UP,
+                    keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
+                    InputDevice.SOURCE_KEYBOARD);
+            if(injectEventSync(upEvent)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Rotates right and also freezes rotation in that position by
+     * disabling the sensors. If you want to un-freeze the rotation
+     * and re-enable the sensors see {@link #unfreezeRotation()}. Note
+     * that doing so may cause the screen contents to rotate
+     * depending on the current physical position of the test device.
+     * @throws RemoteException
+     */
+    public void setRotationRight() {
+        mUiAutomatorBridge.setRotation(UiAutomation.ROTATION_FREEZE_270);
+    }
+
+    /**
+     * Rotates left and also freezes rotation in that position by
+     * disabling the sensors. If you want to un-freeze the rotation
+     * and re-enable the sensors see {@link #unfreezeRotation()}. Note
+     * that doing so may cause the screen contents to rotate
+     * depending on the current physical position of the test device.
+     * @throws RemoteException
+     */
+    public void setRotationLeft() {
+        mUiAutomatorBridge.setRotation(UiAutomation.ROTATION_FREEZE_90);
+    }
+
+    /**
+     * Rotates up and also freezes rotation in that position by
+     * disabling the sensors. If you want to un-freeze the rotation
+     * and re-enable the sensors see {@link #unfreezeRotation()}. Note
+     * that doing so may cause the screen contents to rotate
+     * depending on the current physical position of the test device.
+     * @throws RemoteException
+     */
+    public void setRotationNatural() {
+        mUiAutomatorBridge.setRotation(UiAutomation.ROTATION_FREEZE_0);
+    }
+
+    /**
+     * Disables the sensors and freezes the device rotation at its
+     * current rotation state.
+     * @throws RemoteException
+     */
+    public void freezeRotation() {
+        mUiAutomatorBridge.setRotation(UiAutomation.ROTATION_FREEZE_CURRENT);
+    }
+
+    /**
+     * Re-enables the sensors and un-freezes the device rotation
+     * allowing its contents to rotate with the device physical rotation.
+     * @throws RemoteException
+     */
+    public void unfreezeRotation() {
+        mUiAutomatorBridge.setRotation(UiAutomation.ROTATION_UNFREEZE);
+    }
+
+    /**
+     * This method simply presses the power button if the screen is OFF else
+     * it does nothing if the screen is already ON.
+     * @return true if the device was asleep else false
+     * @throws RemoteException
+     */
+    public boolean wakeDevice() throws RemoteException {
+        if(!isScreenOn()) {
+            sendKey(KeyEvent.KEYCODE_POWER, 0);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * This method simply presses the power button if the screen is ON else
+     * it does nothing if the screen is already OFF.
+     * @return true if the device was awake else false
+     * @throws RemoteException
+     */
+    public boolean sleepDevice() throws RemoteException {
+        if(isScreenOn()) {
+            this.sendKey(KeyEvent.KEYCODE_POWER, 0);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Checks the power manager if the screen is ON
+     * @return true if the screen is ON else false
+     * @throws RemoteException
+     */
+    public boolean isScreenOn() throws RemoteException {
+        return mUiAutomatorBridge.isScreenOn();
+    }
+
+    private boolean injectEventSync(InputEvent event) {
+        return mUiAutomatorBridge.injectInputEvent(event, true);
+    }
+
+    private int getPointerAction(int motionEnvent, int index) {
+        return motionEnvent + (index << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
+    }
+
+    /**
+     * Performs a multi-touch gesture
+     *
+     * Takes a series of touch coordinates for at least 2 pointers. Each pointer must have
+     * all of its touch steps defined in an array of {@link PointerCoords}. By having the ability
+     * to specify the touch points along the path of a pointer, the caller is able to specify
+     * complex gestures like circles, irregular shapes etc, where each pointer may take a
+     * different path.
+     *
+     * To create a single point on a pointer's touch path
+     * <code>
+     *       PointerCoords p = new PointerCoords();
+     *       p.x = stepX;
+     *       p.y = stepY;
+     *       p.pressure = 1;
+     *       p.size = 1;
+     * </code>
+     * @param touches each array of {@link PointerCoords} constitute a single pointer's touch path.
+     *        Multiple {@link PointerCoords} arrays constitute multiple pointers, each with its own
+     *        path. Each {@link PointerCoords} in an array constitute a point on a pointer's path.
+     * @return <code>true</code> if all points on all paths are injected successfully, <code>false
+     *        </code>otherwise
+     * @since API Level 18
+     */
+    public boolean performMultiPointerGesture(PointerCoords[] ... touches) {
+        boolean ret = true;
+        if (touches.length < 2) {
+            throw new IllegalArgumentException("Must provide coordinates for at least 2 pointers");
+        }
+
+        // Get the pointer with the max steps to inject.
+        int maxSteps = 0;
+        for (int x = 0; x < touches.length; x++)
+            maxSteps = (maxSteps < touches[x].length) ? touches[x].length : maxSteps;
+
+        // specify the properties for each pointer as finger touch
+        PointerProperties[] properties = new PointerProperties[touches.length];
+        PointerCoords[] pointerCoords = new PointerCoords[touches.length];
+        for (int x = 0; x < touches.length; x++) {
+            PointerProperties prop = new PointerProperties();
+            prop.id = x;
+            prop.toolType = MotionEvent.TOOL_TYPE_FINGER;
+            properties[x] = prop;
+
+            // for each pointer set the first coordinates for touch down
+            pointerCoords[x] = touches[x][0];
+        }
+
+        // Touch down all pointers
+        long downTime = SystemClock.uptimeMillis();
+        MotionEvent event;
+        event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 1,
+                properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+        ret &= injectEventSync(event);
+
+        for (int x = 1; x < touches.length; x++) {
+            event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(),
+                    getPointerAction(MotionEvent.ACTION_POINTER_DOWN, x), x + 1, properties,
+                    pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+            ret &= injectEventSync(event);
+        }
+
+        // Move all pointers
+        for (int i = 1; i < maxSteps - 1; i++) {
+            // for each pointer
+            for (int x = 0; x < touches.length; x++) {
+                // check if it has coordinates to move
+                if (touches[x].length > i)
+                    pointerCoords[x] = touches[x][i];
+                else
+                    pointerCoords[x] = touches[x][touches[x].length - 1];
+            }
+
+            event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(),
+                    MotionEvent.ACTION_MOVE, touches.length, properties, pointerCoords, 0, 0, 1, 1,
+                    0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+
+            ret &= injectEventSync(event);
+            SystemClock.sleep(MOTION_EVENT_INJECTION_DELAY_MILLIS);
+        }
+
+        // For each pointer get the last coordinates
+        for (int x = 0; x < touches.length; x++)
+            pointerCoords[x] = touches[x][touches[x].length - 1];
+
+        // touch up
+        for (int x = 1; x < touches.length; x++) {
+            event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(),
+                    getPointerAction(MotionEvent.ACTION_POINTER_UP, x), x + 1, properties,
+                    pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+            ret &= injectEventSync(event);
+        }
+
+        Log.i(LOG_TAG, "x " + pointerCoords[0].x);
+        // first to touch down is last up
+        event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 1,
+                properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+        ret &= injectEventSync(event);
+        return ret;
+    }
+
+    /**
+     * Simulates a short press on the Recent Apps button.
+     *
+     * @return true if successful, else return false
+     * @since API Level 18
+     */
+    public boolean toggleRecentApps() {
+        return mUiAutomatorBridge.performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_RECENTS);
+    }
+
+    /**
+     * Opens the notification shade
+     *
+     * @return true if successful, else return false
+     * @since API Level 18
+     */
+    public boolean openNotification() {
+        return mUiAutomatorBridge.performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS);
+    }
+
+    /**
+     * Opens the quick settings shade
+     *
+     * @return true if successful, else return false
+     * @since API Level 18
+     */
+    public boolean openQuickSettings() {
+        return mUiAutomatorBridge.performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS);
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/QueryController.java b/library/core-src/com/android/uiautomator/core/QueryController.java
new file mode 100644
index 0000000..6931528
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/QueryController.java
@@ -0,0 +1,521 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+import android.app.UiAutomation.OnAccessibilityEventListener;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+
+/**
+ * The QueryController main purpose is to translate a {@link UiSelector} selectors to
+ * {@link AccessibilityNodeInfo}. This is all this controller does.
+ */
+class QueryController {
+
+    private static final String LOG_TAG = QueryController.class.getSimpleName();
+
+    private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
+    private static final boolean VERBOSE = Log.isLoggable(LOG_TAG, Log.VERBOSE);
+
+    private final UiAutomatorBridge mUiAutomatorBridge;
+
+    private final Object mLock = new Object();
+
+    private String mLastActivityName = null;
+
+    // During a pattern selector search, the recursive pattern search
+    // methods will track their counts and indexes here.
+    private int mPatternCounter = 0;
+    private int mPatternIndexer = 0;
+
+    // These help show each selector's search context as it relates to the previous sub selector
+    // matched. When a compound selector fails, it is hard to tell which part of it is failing.
+    // Seeing how a selector is being parsed and which sub selector failed within a long list
+    // of compound selectors is very helpful.
+    private int mLogIndent = 0;
+    private int mLogParentIndent = 0;
+
+    private String mLastTraversedText = "";
+
+    public QueryController(UiAutomatorBridge bridge) {
+        mUiAutomatorBridge = bridge;
+        bridge.setOnAccessibilityEventListener(new OnAccessibilityEventListener() {
+            @Override
+            public void onAccessibilityEvent(AccessibilityEvent event) {
+                synchronized (mLock) {
+                    switch(event.getEventType()) {
+                        case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
+                            // don't trust event.getText(), check for nulls
+                            if (event.getText() != null && event.getText().size() > 0) {
+                                if(event.getText().get(0) != null)
+                                    mLastActivityName = event.getText().get(0).toString();
+                            }
+                           break;
+                        case AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY:
+                            // don't trust event.getText(), check for nulls
+                            if (event.getText() != null && event.getText().size() > 0)
+                                if(event.getText().get(0) != null)
+                                    mLastTraversedText = event.getText().get(0).toString();
+                            if (DEBUG)
+                                Log.d(LOG_TAG, "Last text selection reported: " +
+                                        mLastTraversedText);
+                            break;
+                    }
+                    mLock.notifyAll();
+                }
+            }
+        });
+    }
+
+    /**
+     * Returns the last text selection reported by accessibility
+     * event TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY. One way to cause
+     * this event is using a DPad arrows to focus on UI elements.
+     */
+    public String getLastTraversedText() {
+        mUiAutomatorBridge.waitForIdle();
+        synchronized (mLock) {
+            if (mLastTraversedText.length() > 0) {
+                return mLastTraversedText;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Clears the last text selection value saved from the TYPE_VIEW_TEXT_SELECTION_CHANGED
+     * event
+     */
+    public void clearLastTraversedText() {
+        mUiAutomatorBridge.waitForIdle();
+        synchronized (mLock) {
+            mLastTraversedText = "";
+        }
+    }
+
+    private void initializeNewSearch() {
+        mPatternCounter = 0;
+        mPatternIndexer = 0;
+        mLogIndent = 0;
+        mLogParentIndent = 0;
+    }
+
+    /**
+     * Counts the instances of the selector group. The selector must be in the following
+     * format: [container_selector, PATTERN=[INSTANCE=x, PATTERN=[the_pattern]]
+     * where the container_selector is used to find the containment region to search for patterns
+     * and the INSTANCE=x is the instance of the_pattern to return.
+     * @param selector
+     * @return number of pattern matches. Returns 0 for all other cases.
+     */
+    public int getPatternCount(UiSelector selector) {
+        findAccessibilityNodeInfo(selector, true /*counting*/);
+        return mPatternCounter;
+    }
+
+    /**
+     * Main search method for translating By selectors to AccessibilityInfoNodes
+     * @param selector
+     * @return AccessibilityNodeInfo
+     */
+    public AccessibilityNodeInfo findAccessibilityNodeInfo(UiSelector selector) {
+        return findAccessibilityNodeInfo(selector, false);
+    }
+
+    protected AccessibilityNodeInfo findAccessibilityNodeInfo(UiSelector selector,
+            boolean isCounting) {
+        mUiAutomatorBridge.waitForIdle();
+        initializeNewSearch();
+
+        if (DEBUG)
+            Log.d(LOG_TAG, "Searching: " + selector);
+
+        synchronized (mLock) {
+            AccessibilityNodeInfo rootNode = getRootNode();
+            if (rootNode == null) {
+                Log.e(LOG_TAG, "Cannot proceed when root node is null. Aborted search");
+                return null;
+            }
+
+            // Copy so that we don't modify the original's sub selectors
+            UiSelector uiSelector = new UiSelector(selector);
+            return translateCompoundSelector(uiSelector, rootNode, isCounting);
+        }
+    }
+
+    /**
+     * Gets the root node from accessibility and if it fails to get one it will
+     * retry every 250ms for up to 1000ms.
+     * @return null if no root node is obtained
+     */
+    protected AccessibilityNodeInfo getRootNode() {
+        final int maxRetry = 4;
+        final long waitInterval = 250;
+        AccessibilityNodeInfo rootNode = null;
+        for(int x = 0; x < maxRetry; x++) {
+            rootNode = mUiAutomatorBridge.getRootInActiveWindow();
+            if (rootNode != null) {
+                return rootNode;
+            }
+            if(x < maxRetry - 1) {
+                Log.e(LOG_TAG, "Got null root node from accessibility - Retrying...");
+                SystemClock.sleep(waitInterval);
+            }
+        }
+        return rootNode;
+    }
+
+    /**
+     * A compoundSelector encapsulate both Regular and Pattern selectors. The formats follows:
+     * <p/>
+     * regular_selector = By[attributes... CHILD=By[attributes... CHILD=By[....]]]
+     * <br/>
+     * pattern_selector = ...CONTAINER=By[..] PATTERN=By[instance=x PATTERN=[regular_selector]
+     * <br/>
+     * compound_selector = [regular_selector [pattern_selector]]
+     * <p/>
+     * regular_selectors are the most common form of selectors and the search for them
+     * is straightforward. On the other hand pattern_selectors requires search to be
+     * performed as in regular_selector but where regular_selector search returns immediately
+     * upon a successful match, the search for pattern_selector continues until the
+     * requested matched _instance_ of that pattern is matched.
+     * <p/>
+     * Counting UI objects requires using pattern_selectors. The counting search is the same
+     * as a pattern_search however we're not looking to match an instance of the pattern but
+     * rather continuously walking the accessibility node hierarchy while counting matched
+     * patterns, until the end of the tree.
+     * <p/>
+     * If both present, order of parsing begins with CONTAINER followed by PATTERN then the
+     * top most selector is processed as regular_selector within the context of the previous
+     * CONTAINER and its PATTERN information. If neither is present then the top selector is
+     * directly treated as regular_selector. So the presence of a CONTAINER and PATTERN within
+     * a selector simply dictates that the selector matching will be constraint to the sub tree
+     * node where the CONTAINER and its child PATTERN have identified.
+     * @param selector
+     * @param fromNode
+     * @param isCounting
+     * @return AccessibilityNodeInfo
+     */
+    private AccessibilityNodeInfo translateCompoundSelector(UiSelector selector,
+            AccessibilityNodeInfo fromNode, boolean isCounting) {
+
+        // Start translating compound selectors by translating the regular_selector first
+        // The regular_selector is then used as a container for any optional pattern_selectors
+        // that may or may not be specified.
+        if(selector.hasContainerSelector())
+            // nested pattern selectors
+            if(selector.getContainerSelector().hasContainerSelector()) {
+                fromNode = translateCompoundSelector(
+                        selector.getContainerSelector(), fromNode, false);
+                initializeNewSearch();
+            } else
+                fromNode = translateReqularSelector(selector.getContainerSelector(), fromNode);
+        else
+            fromNode = translateReqularSelector(selector, fromNode);
+
+        if(fromNode == null) {
+            if (DEBUG)
+                Log.d(LOG_TAG, "Container selector not found: " + selector.dumpToString(false));
+            return null;
+        }
+
+        if(selector.hasPatternSelector()) {
+            fromNode = translatePatternSelector(selector.getPatternSelector(),
+                    fromNode, isCounting);
+
+            if (isCounting) {
+                Log.i(LOG_TAG, String.format(
+                        "Counted %d instances of: %s", mPatternCounter, selector));
+                return null;
+            } else {
+                if(fromNode == null) {
+                    if (DEBUG)
+                        Log.d(LOG_TAG, "Pattern selector not found: " +
+                                selector.dumpToString(false));
+                    return null;
+                }
+            }
+        }
+
+        // translate any additions to the selector that may have been added by tests
+        // with getChild(By selector) after a container and pattern selectors
+        if(selector.hasContainerSelector() || selector.hasPatternSelector()) {
+            if(selector.hasChildSelector() || selector.hasParentSelector())
+                fromNode = translateReqularSelector(selector, fromNode);
+        }
+
+        if(fromNode == null) {
+            if (DEBUG)
+                Log.d(LOG_TAG, "Object Not Found for selector " + selector);
+            return null;
+        }
+        Log.i(LOG_TAG, String.format("Matched selector: %s <<==>> [%s]", selector, fromNode));
+        return fromNode;
+    }
+
+    /**
+     * Used by the {@link #translateCompoundSelector(UiSelector, AccessibilityNodeInfo, boolean)}
+     * to translate the regular_selector portion. It has the following format:
+     * <p/>
+     * regular_selector = By[attributes... CHILD=By[attributes... CHILD=By[....]]]<br/>
+     * <p/>
+     * regular_selectors are the most common form of selectors and the search for them
+     * is straightforward. This method will only look for CHILD or PARENT sub selectors.
+     * <p/>
+     * @param selector
+     * @param fromNode
+     * @return AccessibilityNodeInfo if found else null
+     */
+    private AccessibilityNodeInfo translateReqularSelector(UiSelector selector,
+            AccessibilityNodeInfo fromNode) {
+
+        return findNodeRegularRecursive(selector, fromNode, 0);
+    }
+
+    private AccessibilityNodeInfo findNodeRegularRecursive(UiSelector subSelector,
+            AccessibilityNodeInfo fromNode, int index) {
+
+        if (subSelector.isMatchFor(fromNode, index)) {
+            if (DEBUG) {
+                Log.d(LOG_TAG, formatLog(String.format("%s",
+                        subSelector.dumpToString(false))));
+            }
+            if(subSelector.isLeaf()) {
+                return fromNode;
+            }
+            if(subSelector.hasChildSelector()) {
+                mLogIndent++; // next selector
+                subSelector = subSelector.getChildSelector();
+                if(subSelector == null) {
+                    Log.e(LOG_TAG, "Error: A child selector without content");
+                    return null; // there is an implementation fault
+                }
+            } else if(subSelector.hasParentSelector()) {
+                mLogIndent++; // next selector
+                subSelector = subSelector.getParentSelector();
+                if(subSelector == null) {
+                    Log.e(LOG_TAG, "Error: A parent selector without content");
+                    return null; // there is an implementation fault
+                }
+                // the selector requested we start at this level from
+                // the parent node from the one we just matched
+                fromNode = fromNode.getParent();
+                if(fromNode == null)
+                    return null;
+            }
+        }
+
+        int childCount = fromNode.getChildCount();
+        boolean hasNullChild = false;
+        for (int i = 0; i < childCount; i++) {
+            AccessibilityNodeInfo childNode = fromNode.getChild(i);
+            if (childNode == null) {
+                Log.w(LOG_TAG, String.format(
+                        "AccessibilityNodeInfo returned a null child (%d of %d)", i, childCount));
+                if (!hasNullChild) {
+                    Log.w(LOG_TAG, String.format("parent = %s", fromNode.toString()));
+                }
+                hasNullChild = true;
+                continue;
+            }
+            if (!childNode.isVisibleToUser()) {
+                if (VERBOSE)
+                    Log.v(LOG_TAG,
+                            String.format("Skipping invisible child: %s", childNode.toString()));
+                continue;
+            }
+            AccessibilityNodeInfo retNode = findNodeRegularRecursive(subSelector, childNode, i);
+            if (retNode != null) {
+                return retNode;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Used by the {@link #translateCompoundSelector(UiSelector, AccessibilityNodeInfo, boolean)}
+     * to translate the pattern_selector portion. It has the following format:
+     * <p/>
+     * pattern_selector = ... PATTERN=By[instance=x PATTERN=[regular_selector]]<br/>
+     * <p/>
+     * pattern_selectors requires search to be performed as regular_selector but where
+     * regular_selector search returns immediately upon a successful match, the search for
+     * pattern_selector continues until the requested matched instance of that pattern is
+     * encountered.
+     * <p/>
+     * Counting UI objects requires using pattern_selectors. The counting search is the same
+     * as a pattern_search however we're not looking to match an instance of the pattern but
+     * rather continuously walking the accessibility node hierarchy while counting patterns
+     * until the end of the tree.
+     * @param subSelector
+     * @param fromNode
+     * @param isCounting
+     * @return null of node is not found or if counting mode is true.
+     * See {@link #translateCompoundSelector(UiSelector, AccessibilityNodeInfo, boolean)}
+     */
+    private AccessibilityNodeInfo translatePatternSelector(UiSelector subSelector,
+            AccessibilityNodeInfo fromNode, boolean isCounting) {
+
+        if(subSelector.hasPatternSelector()) {
+            // Since pattern_selectors are also the type of selectors used when counting,
+            // we check if this is a counting run or an indexing run
+            if(isCounting)
+                //since we're counting, we reset the indexer so to terminates the search when
+                // the end of tree is reached. The count will be in mPatternCount
+                mPatternIndexer = -1;
+            else
+                // terminates the search once we match the pattern's instance
+                mPatternIndexer = subSelector.getInstance();
+
+            // A pattern is wrapped in a PATTERN[instance=x PATTERN[the_pattern]]
+            subSelector = subSelector.getPatternSelector();
+            if(subSelector == null) {
+                Log.e(LOG_TAG, "Pattern portion of the selector is null or not defined");
+                return null; // there is an implementation fault
+            }
+            // save the current indent level as parent indent before pattern searches
+            // begin under the current tree position.
+            mLogParentIndent = ++mLogIndent;
+            return findNodePatternRecursive(subSelector, fromNode, 0, subSelector);
+        }
+
+        Log.e(LOG_TAG, "Selector must have a pattern selector defined"); // implementation fault?
+        return null;
+    }
+
+    private AccessibilityNodeInfo findNodePatternRecursive(
+            UiSelector subSelector, AccessibilityNodeInfo fromNode, int index,
+            UiSelector originalPattern) {
+
+        if (subSelector.isMatchFor(fromNode, index)) {
+            if(subSelector.isLeaf()) {
+                if(mPatternIndexer == 0) {
+                    if (DEBUG)
+                        Log.d(LOG_TAG, formatLog(
+                                String.format("%s", subSelector.dumpToString(false))));
+                    return fromNode;
+                } else {
+                    if (DEBUG)
+                        Log.d(LOG_TAG, formatLog(
+                                String.format("%s", subSelector.dumpToString(false))));
+                    mPatternCounter++; //count the pattern matched
+                    mPatternIndexer--; //decrement until zero for the instance requested
+
+                    // At a leaf selector within a group and still not instance matched
+                    // then reset the  selector to continue search from current position
+                    // in the accessibility tree for the next pattern match up until the
+                    // pattern index hits 0.
+                    subSelector = originalPattern;
+                    // starting over with next pattern search so reset to parent level
+                    mLogIndent = mLogParentIndent;
+                }
+            } else {
+                if (DEBUG)
+                    Log.d(LOG_TAG, formatLog(
+                            String.format("%s", subSelector.dumpToString(false))));
+
+                if(subSelector.hasChildSelector()) {
+                    mLogIndent++; // next selector
+                    subSelector = subSelector.getChildSelector();
+                    if(subSelector == null) {
+                        Log.e(LOG_TAG, "Error: A child selector without content");
+                        return null;
+                    }
+                } else if(subSelector.hasParentSelector()) {
+                    mLogIndent++; // next selector
+                    subSelector = subSelector.getParentSelector();
+                    if(subSelector == null) {
+                        Log.e(LOG_TAG, "Error: A parent selector without content");
+                        return null;
+                    }
+                    fromNode = fromNode.getParent();
+                    if(fromNode == null)
+                        return null;
+                }
+            }
+        }
+
+        int childCount = fromNode.getChildCount();
+        boolean hasNullChild = false;
+        for (int i = 0; i < childCount; i++) {
+            AccessibilityNodeInfo childNode = fromNode.getChild(i);
+            if (childNode == null) {
+                Log.w(LOG_TAG, String.format(
+                        "AccessibilityNodeInfo returned a null child (%d of %d)", i, childCount));
+                if (!hasNullChild) {
+                    Log.w(LOG_TAG, String.format("parent = %s", fromNode.toString()));
+                }
+                hasNullChild = true;
+                continue;
+            }
+            if (!childNode.isVisibleToUser()) {
+                if (DEBUG)
+                    Log.d(LOG_TAG,
+                        String.format("Skipping invisible child: %s", childNode.toString()));
+                continue;
+            }
+            AccessibilityNodeInfo retNode = findNodePatternRecursive(
+                    subSelector, childNode, i, originalPattern);
+            if (retNode != null) {
+                return retNode;
+            }
+        }
+        return null;
+    }
+
+    public AccessibilityNodeInfo getAccessibilityRootNode() {
+        return mUiAutomatorBridge.getRootInActiveWindow();
+    }
+
+    /**
+     * Last activity to report accessibility events.
+     * @deprecated The results returned should be considered unreliable
+     * @return String name of activity
+     */
+    @Deprecated
+    public String getCurrentActivityName() {
+        mUiAutomatorBridge.waitForIdle();
+        synchronized (mLock) {
+            return mLastActivityName;
+        }
+    }
+
+    /**
+     * Last package to report accessibility events
+     * @return String name of package
+     */
+    public String getCurrentPackageName() {
+        mUiAutomatorBridge.waitForIdle();
+        AccessibilityNodeInfo rootNode = getRootNode();
+        if (rootNode == null)
+            return null;
+        return rootNode.getPackageName() != null ? rootNode.getPackageName().toString() : null;
+    }
+
+    private String formatLog(String str) {
+        StringBuilder l = new StringBuilder();
+        for(int space = 0; space < mLogIndent; space++)
+            l.append(". . ");
+        if(mLogIndent > 0)
+            l.append(String.format(". . [%d]: %s", mPatternCounter, str));
+        else
+            l.append(String.format(". . [%d]: %s", mPatternCounter, str));
+        return l.toString();
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/Tracer.java b/library/core-src/com/android/uiautomator/core/Tracer.java
new file mode 100644
index 0000000..d574fc0
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/Tracer.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Class that creates traces of the calls to the UiAutomator API and outputs the
+ * traces either to logcat or a logfile. Each public method in the UiAutomator
+ * that needs to be traced should include a call to Tracer.trace in the
+ * beginning. Tracing is turned off by defualt and needs to be enabled
+ * explicitly.
+ * @hide
+ */
+public class Tracer {
+    private static final String UNKNOWN_METHOD_STRING = "(unknown method)";
+    private static final String UIAUTOMATOR_PACKAGE = "com.android.uiautomator.core";
+    private static final int CALLER_LOCATION = 6;
+    private static final int METHOD_TO_TRACE_LOCATION = 5;
+    private static final int MIN_STACK_TRACE_LENGTH = 7;
+
+    /**
+     * Enum that determines where the trace output goes. It can go to either
+     * logcat, log file or both.
+     */
+    public enum Mode {
+        NONE,
+        FILE,
+        LOGCAT,
+        ALL
+    }
+
+    private interface TracerSink {
+        public void log(String message);
+
+        public void close();
+    }
+
+    private class FileSink implements TracerSink {
+        private PrintWriter mOut;
+        private SimpleDateFormat mDateFormat;
+
+        public FileSink(File file) throws FileNotFoundException {
+            mOut = new PrintWriter(file);
+            mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
+        }
+
+        public void log(String message) {
+            mOut.printf("%s %s\n", mDateFormat.format(new Date()), message);
+        }
+
+        public void close() {
+            mOut.close();
+        }
+    }
+
+    private class LogcatSink implements TracerSink {
+
+        private static final String LOGCAT_TAG = "UiAutomatorTrace";
+
+        public void log(String message) {
+            Log.i(LOGCAT_TAG, message);
+        }
+
+        public void close() {
+            // nothing is needed
+        }
+    }
+
+    private Mode mCurrentMode = Mode.NONE;
+    private List<TracerSink> mSinks = new ArrayList<TracerSink>();
+    private File mOutputFile;
+
+    private static Tracer mInstance = null;
+
+    /**
+     * Returns a reference to an instance of the tracer. Useful to set the
+     * parameters before the trace is collected.
+     *
+     * @return
+     */
+    public static Tracer getInstance() {
+        if (mInstance == null) {
+            mInstance = new Tracer();
+        }
+        return mInstance;
+    }
+
+    /**
+     * Sets where the trace output will go. Can be either be logcat or a file or
+     * both. Setting this to NONE will turn off tracing.
+     *
+     * @param mode
+     */
+    public void setOutputMode(Mode mode) {
+        closeSinks();
+        mCurrentMode = mode;
+        try {
+            switch (mode) {
+                case FILE:
+                    if (mOutputFile == null) {
+                        throw new IllegalArgumentException("Please provide a filename before " +
+                                "attempting write trace to a file");
+                    }
+                    mSinks.add(new FileSink(mOutputFile));
+                    break;
+                case LOGCAT:
+                    mSinks.add(new LogcatSink());
+                    break;
+                case ALL:
+                    mSinks.add(new LogcatSink());
+                    if (mOutputFile == null) {
+                        throw new IllegalArgumentException("Please provide a filename before " +
+                                "attempting write trace to a file");
+                    }
+                    mSinks.add(new FileSink(mOutputFile));
+                    break;
+                default:
+                    break;
+            }
+        } catch (FileNotFoundException e) {
+            Log.w("Tracer", "Could not open log file: " + e.getMessage());
+        }
+    }
+
+    private void closeSinks() {
+        for (TracerSink sink : mSinks) {
+            sink.close();
+        }
+        mSinks.clear();
+    }
+
+    /**
+     * Sets the name of the log file where tracing output will be written if the
+     * tracer is set to write to a file.
+     *
+     * @param filename name of the log file.
+     */
+    public void setOutputFilename(String filename) {
+        mOutputFile = new File(filename);
+    }
+
+    private void doTrace(Object[] arguments) {
+        if (mCurrentMode == Mode.NONE) {
+            return;
+        }
+
+        String caller = getCaller();
+        if (caller == null) {
+            return;
+        }
+
+        log(String.format("%s (%s)", caller, join(", ", arguments)));
+    }
+
+    private void log(String message) {
+        for (TracerSink sink : mSinks) {
+            sink.log(message);
+        }
+    }
+
+    /**
+     * Queries whether the tracing is enabled.
+     * @return true if tracing is enabled, false otherwise.
+     */
+    public boolean isTracingEnabled() {
+        return mCurrentMode != Mode.NONE;
+    }
+
+    /**
+     * Public methods in the UiAutomator should call this function to generate a
+     * trace. The trace will include the method thats is being called, it's
+     * arguments and where in the user's code the method is called from. If a
+     * public method is called internally from UIAutomator then this will not
+     * output a trace entry. Only calls from outise the UiAutomator package will
+     * produce output.
+     *
+     * Special note about array arguments. You can safely pass arrays of reference types
+     * to this function. Like String[] or Integer[]. The trace function will print their
+     * contents by calling toString() on each of the elements. This will not work for
+     * array of primitive types like int[] or float[]. Before passing them to this function
+     * convert them to arrays of reference types manually. Example: convert int[] to Integer[].
+     *
+     * @param arguments arguments of the method being traced.
+     */
+    public static void trace(Object... arguments) {
+        Tracer.getInstance().doTrace(arguments);
+    }
+
+    private static String join(String separator, Object[] strings) {
+        if (strings.length == 0)
+            return "";
+
+        StringBuilder builder = new StringBuilder(objectToString(strings[0]));
+        for (int i = 1; i < strings.length; i++) {
+            builder.append(separator);
+            builder.append(objectToString(strings[i]));
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Special toString method to handle arrays. If the argument is a normal object then this will
+     * return normal output of obj.toString(). If the argument is an array this will return a
+     * string representation of the elements of the array.
+     *
+     * This method will not work for arrays of primitive types. Arrays of primitive types are
+     * expected to be converted manually by the caller. If the array is not converter then
+     * this function will only output "[...]" instead of the contents of the array.
+     *
+     * @param obj object to convert to a string
+     * @return String representation of the object.
+     */
+    private static String objectToString(Object obj) {
+        if (obj.getClass().isArray()) {
+            if (obj instanceof Object[]) {
+                return Arrays.deepToString((Object[])obj);
+            } else {
+                return "[...]";
+            }
+        } else {
+            return obj.toString();
+        }
+    }
+
+    /**
+     * This method outputs which UiAutomator method was called and where in the
+     * user code it was called from. If it can't deside which method is called
+     * it will output "(unknown method)". If the method was called from inside
+     * the UiAutomator then it returns null.
+     *
+     * @return name of the method called and where it was called from. Null if
+     *         method was called from inside UiAutomator.
+     */
+    private static String getCaller() {
+        StackTraceElement stackTrace[] = Thread.currentThread().getStackTrace();
+        if (stackTrace.length < MIN_STACK_TRACE_LENGTH) {
+            return UNKNOWN_METHOD_STRING;
+        }
+
+        StackTraceElement caller = stackTrace[METHOD_TO_TRACE_LOCATION];
+        StackTraceElement previousCaller = stackTrace[CALLER_LOCATION];
+
+        if (previousCaller.getClassName().startsWith(UIAUTOMATOR_PACKAGE)) {
+            return null;
+        }
+
+        int indexOfDot = caller.getClassName().lastIndexOf('.');
+        if (indexOfDot < 0) {
+            indexOfDot = 0;
+        }
+
+        if (indexOfDot + 1 >= caller.getClassName().length()) {
+            return UNKNOWN_METHOD_STRING;
+        }
+
+        String shortClassName = caller.getClassName().substring(indexOfDot + 1);
+        return String.format("%s.%s from %s() at %s:%d", shortClassName, caller.getMethodName(),
+                previousCaller.getMethodName(), previousCaller.getFileName(),
+                previousCaller.getLineNumber());
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/UiAutomatorBridge.java b/library/core-src/com/android/uiautomator/core/UiAutomatorBridge.java
new file mode 100644
index 0000000..bc5bc8e
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/UiAutomatorBridge.java
@@ -0,0 +1,143 @@
+package com.android.uiautomator.core;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.UiAutomation;
+import android.app.UiAutomation.AccessibilityEventFilter;
+import android.app.UiAutomation.OnAccessibilityEventListener;
+import android.graphics.Bitmap;
+import android.util.Log;
+import android.view.Display;
+import android.view.InputEvent;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * @hide
+ */
+public abstract class UiAutomatorBridge {
+
+    private static final String LOG_TAG = UiAutomatorBridge.class.getSimpleName();
+
+   /**
+    * This value has the greatest bearing on the appearance of test execution speeds.
+    * This value is used as the minimum time to wait before considering the UI idle after
+    * each action.
+    */
+    private static final long QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE = 500;//ms
+
+   /**
+    * This is the maximum time the automation will wait for the UI to go idle. Execution
+    * will resume normally anyway. This is to prevent waiting forever on display updates
+    * that may be related to spinning wheels or progress updates of sorts etc...
+    */
+    private static final long TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE = 1000 * 10;//ms
+
+    private final UiAutomation mUiAutomation;
+
+    private final InteractionController mInteractionController;
+
+    private final QueryController mQueryController;
+
+    UiAutomatorBridge(UiAutomation uiAutomation) {
+        mUiAutomation = uiAutomation;
+        mInteractionController = new InteractionController(this);
+        mQueryController = new QueryController(this);
+    }
+
+    InteractionController getInteractionController() {
+        return mInteractionController;
+    }
+
+    QueryController getQueryController() {
+        return mQueryController;
+    }
+
+    public void setOnAccessibilityEventListener(OnAccessibilityEventListener listener) {
+        mUiAutomation.setOnAccessibilityEventListener(listener);
+    }
+
+    public AccessibilityNodeInfo getRootInActiveWindow() {
+        return mUiAutomation.getRootInActiveWindow();
+    }
+
+    public boolean injectInputEvent(InputEvent event, boolean sync) {
+        return mUiAutomation.injectInputEvent(event, sync);
+    }
+
+    public boolean setRotation(int rotation) {
+        return mUiAutomation.setRotation(rotation);
+    }
+
+    public void setCompressedLayoutHierarchy(boolean compressed) {
+        AccessibilityServiceInfo info = mUiAutomation.getServiceInfo();
+        if (compressed)
+            info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+        else
+            info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+        mUiAutomation.setServiceInfo(info);
+    }
+
+    public abstract int getRotation();
+
+    public abstract boolean isScreenOn();
+
+    public void waitForIdle() {
+        waitForIdle(TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
+    }
+
+    public void waitForIdle(long timeout) {
+        try {
+            mUiAutomation.waitForIdle(QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE, timeout);
+        } catch (TimeoutException te) {
+            Log.w(LOG_TAG, "Could not detect idle state.", te);
+        }
+    }
+
+    public AccessibilityEvent executeCommandAndWaitForAccessibilityEvent(Runnable command,
+            AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException {
+        return mUiAutomation.executeAndWaitForEvent(command,
+                filter, timeoutMillis);
+    }
+
+    public boolean takeScreenshot(File storePath, int quality) {
+        Bitmap screenshot = mUiAutomation.takeScreenshot();
+        if (screenshot == null) {
+            return false;
+        }
+        BufferedOutputStream bos = null;
+        try {
+            bos = new BufferedOutputStream(new FileOutputStream(storePath));
+            if (bos != null) {
+                screenshot.compress(Bitmap.CompressFormat.PNG, quality, bos);
+                bos.flush();
+            }
+        } catch (IOException ioe) {
+            Log.e(LOG_TAG, "failed to save screen shot to file", ioe);
+            return false;
+        } finally {
+            if (bos != null) {
+                try {
+                    bos.close();
+                } catch (IOException ioe) {
+                    /* ignore */
+                }
+            }
+            screenshot.recycle();
+        }
+        return true;
+    }
+
+    public boolean performGlobalAction(int action) {
+        return mUiAutomation.performGlobalAction(action);
+    }
+
+    public abstract Display getDefaultDisplay();
+
+    public abstract long getSystemLongPressTime();
+}
diff --git a/library/core-src/com/android/uiautomator/core/UiCollection.java b/library/core-src/com/android/uiautomator/core/UiCollection.java
new file mode 100644
index 0000000..e15beb2
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/UiCollection.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+/**
+ * Used to enumerate a container's UI elements for the purpose of counting,
+ * or targeting a sub elements by a child's text or description.
+ * @since API Level 16
+ */
+public class UiCollection extends UiObject {
+
+    /**
+     * Constructs an instance as described by the selector
+     *
+     * @param selector
+     * @since API Level 16
+     */
+    public UiCollection(UiSelector selector) {
+        super(selector);
+    }
+
+    /**
+     * Searches for child UI element within the constraints of this UiCollection {@link UiSelector}
+     * selector.
+     *
+     * It looks for any child matching the <code>childPattern</code> argument that has
+     * a child UI element anywhere within its sub hierarchy that has content-description text.
+     * The returned UiObject will point at the <code>childPattern</code> instance that matched the
+     * search and not at the identifying child element that matched the content description.</p>
+     *
+     * @param childPattern {@link UiSelector} selector of the child pattern to match and return
+     * @param text String of the identifying child contents of of the <code>childPattern</code>
+     * @return {@link UiObject} pointing at and instance of <code>childPattern</code>
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public UiObject getChildByDescription(UiSelector childPattern, String text)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text);
+        if (text != null) {
+            int count = getChildCount(childPattern);
+            for (int x = 0; x < count; x++) {
+                UiObject row = getChildByInstance(childPattern, x);
+                String nodeDesc = row.getContentDescription();
+                if(nodeDesc != null && nodeDesc.contains(text)) {
+                    return row;
+                }
+                UiObject item = row.getChild(new UiSelector().descriptionContains(text));
+                if (item.exists()) {
+                    return row;
+                }
+            }
+        }
+        throw new UiObjectNotFoundException("for description= \"" + text + "\"");
+    }
+
+    /**
+     * Searches for child UI element within the constraints of this UiCollection {@link UiSelector}
+     * selector.
+     *
+     * It looks for any child matching the <code>childPattern</code> argument that has
+     * a child UI element anywhere within its sub hierarchy that is at the <code>instance</code>
+     * specified. The operation is performed only on the visible items and no scrolling is performed
+     * in this case.
+     *
+     * @param childPattern {@link UiSelector} selector of the child pattern to match and return
+     * @param instance int the desired matched instance of this <code>childPattern</code>
+     * @return {@link UiObject} pointing at and instance of <code>childPattern</code>
+     * @since API Level 16
+     */
+    public UiObject getChildByInstance(UiSelector childPattern, int instance)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, instance);
+        UiSelector patternSelector = UiSelector.patternBuilder(getSelector(),
+                UiSelector.patternBuilder(childPattern).instance(instance));
+        return new UiObject(patternSelector);
+    }
+
+    /**
+     * Searches for child UI element within the constraints of this UiCollection {@link UiSelector}
+     * selector.
+     *
+     * It looks for any child matching the <code>childPattern</code> argument that has
+     * a child UI element anywhere within its sub hierarchy that has text attribute =
+     * <code>text</code>. The returned UiObject will point at the <code>childPattern</code>
+     * instance that matched the search and not at the identifying child element that matched the
+     * text attribute.</p>
+     *
+     * @param childPattern {@link UiSelector} selector of the child pattern to match and return
+     * @param text String of the identifying child contents of of the <code>childPattern</code>
+     * @return {@link UiObject} pointing at and instance of <code>childPattern</code>
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public UiObject getChildByText(UiSelector childPattern, String text)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text);
+        if (text != null) {
+            int count = getChildCount(childPattern);
+            for (int x = 0; x < count; x++) {
+                UiObject row = getChildByInstance(childPattern, x);
+                String nodeText = row.getText();
+                if(text.equals(nodeText)) {
+                    return row;
+                }
+                UiObject item = row.getChild(new UiSelector().text(text));
+                if (item.exists()) {
+                    return row;
+                }
+            }
+        }
+        throw new UiObjectNotFoundException("for text= \"" + text + "\"");
+    }
+
+    /**
+     * Counts child UI element instances matching the <code>childPattern</code>
+     * argument. The method returns the number of matching UI elements that are
+     * currently visible.  The count does not include items of a scrollable list
+     * that are off-screen.
+     *
+     * @param childPattern a {@link UiSelector} that represents the matching child UI
+     * elements to count
+     * @return the number of matched childPattern under the current {@link UiCollection}
+     * @since API Level 16
+     */
+    public int getChildCount(UiSelector childPattern) {
+        Tracer.trace(childPattern);
+        UiSelector patternSelector =
+                UiSelector.patternBuilder(getSelector(), UiSelector.patternBuilder(childPattern));
+        return getQueryController().getPatternCount(patternSelector);
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/UiDevice.java b/library/core-src/com/android/uiautomator/core/UiDevice.java
new file mode 100644
index 0000000..a930eb4
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/UiDevice.java
@@ -0,0 +1,851 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+import android.app.UiAutomation;
+import android.app.UiAutomation.AccessibilityEventFilter;
+import android.graphics.Point;
+import android.os.Build;
+import android.os.Environment;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Display;
+import android.view.KeyEvent;
+import android.view.Surface;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * UiDevice provides access to state information about the device.
+ * You can also use this class to simulate user actions on the device,
+ * such as pressing the d-pad or pressing the Home and Menu buttons.
+ * @since API Level 16
+ */
+public class UiDevice {
+    private static final String LOG_TAG = UiDevice.class.getSimpleName();
+
+    // Sometimes HOME and BACK key presses will generate no events if already on
+    // home page or there is nothing to go back to, Set low timeouts.
+    private static final long KEY_PRESS_EVENT_TIMEOUT = 1 * 1000;
+
+    // store for registered UiWatchers
+    private final HashMap<String, UiWatcher> mWatchers = new HashMap<String, UiWatcher>();
+    private final List<String> mWatchersTriggers = new ArrayList<String>();
+
+    // remember if we're executing in the context of a UiWatcher
+    private boolean mInWatcherContext = false;
+
+    // provides access the {@link QueryController} and {@link InteractionController}
+    private UiAutomatorBridge mUiAutomationBridge;
+
+    // reference to self
+    private static UiDevice sDevice;
+
+    private UiDevice() {
+        /* hide constructor */
+    }
+
+    /**
+     * @hide
+     */
+    public void initialize(UiAutomatorBridge uiAutomatorBridge) {
+        mUiAutomationBridge = uiAutomatorBridge;
+    }
+
+    boolean isInWatcherContext() {
+        return mInWatcherContext;
+    }
+
+    /**
+     * Provides access the {@link QueryController} and {@link InteractionController}
+     * @return {@link ShellUiAutomatorBridge}
+     */
+    UiAutomatorBridge getAutomatorBridge() {
+        if (mUiAutomationBridge == null) {
+            throw new RuntimeException("UiDevice not initialized");
+        }
+        return mUiAutomationBridge;
+    }
+
+    /**
+     * Enables or disables layout hierarchy compression.
+     *
+     * If compression is enabled, the layout hierarchy derived from the Acessibility
+     * framework will only contain nodes that are important for uiautomator
+     * testing. Any unnecessary surrounding layout nodes that make viewing
+     * and searching the hierarchy inefficient are removed.
+     *
+     * @param compressed true to enable compression; else, false to disable
+     * @since API Level 18
+     */
+    public void setCompressedLayoutHeirarchy(boolean compressed) {
+        getAutomatorBridge().setCompressedLayoutHierarchy(compressed);
+    }
+
+    /**
+     * Retrieves a singleton instance of UiDevice
+     *
+     * @return UiDevice instance
+     * @since API Level 16
+     */
+    public static UiDevice getInstance() {
+        if (sDevice == null) {
+            sDevice = new UiDevice();
+        }
+        return sDevice;
+    }
+
+    /**
+     * Returns the display size in dp (device-independent pixel)
+     *
+     * The returned display size is adjusted per screen rotation. Also this will return the actual
+     * size of the screen, rather than adjusted per system decorations (like status bar).
+     *
+     * @return a Point containing the display size in dp
+     */
+    public Point getDisplaySizeDp() {
+        Tracer.trace();
+        Display display = getAutomatorBridge().getDefaultDisplay();
+        Point p = new Point();
+        display.getRealSize(p);
+        DisplayMetrics metrics = new DisplayMetrics();
+        display.getRealMetrics(metrics);
+        float dpx = p.x / metrics.density;
+        float dpy = p.y / metrics.density;
+        p.x = Math.round(dpx);
+        p.y = Math.round(dpy);
+        return p;
+    }
+
+    /**
+     * Retrieves the product name of the device.
+     *
+     * This method provides information on what type of device the test is running on. This value is
+     * the same as returned by invoking #adb shell getprop ro.product.name.
+     *
+     * @return product name of the device
+     * @since API Level 17
+     */
+    public String getProductName() {
+        Tracer.trace();
+        return Build.PRODUCT;
+    }
+
+    /**
+     * Retrieves the text from the last UI traversal event received.
+     *
+     * You can use this method to read the contents in a WebView container
+     * because the accessibility framework fires events
+     * as each text is highlighted. You can write a test to perform
+     * directional arrow presses to focus on different elements inside a WebView,
+     * and call this method to get the text from each traversed element.
+     * If you are testing a view container that can return a reference to a
+     * Document Object Model (DOM) object, your test should use the view's
+     * DOM instead.
+     *
+     * @return text of the last traversal event, else return an empty string
+     * @since API Level 16
+     */
+    public String getLastTraversedText() {
+        Tracer.trace();
+        return getAutomatorBridge().getQueryController().getLastTraversedText();
+    }
+
+    /**
+     * Clears the text from the last UI traversal event.
+     * See {@link #getLastTraversedText()}.
+     * @since API Level 16
+     */
+    public void clearLastTraversedText() {
+        Tracer.trace();
+        getAutomatorBridge().getQueryController().clearLastTraversedText();
+    }
+
+    /**
+     * Simulates a short press on the MENU button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressMenu() {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
+                KeyEvent.KEYCODE_MENU, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
+                KEY_PRESS_EVENT_TIMEOUT);
+    }
+
+    /**
+     * Simulates a short press on the BACK button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressBack() {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
+                KeyEvent.KEYCODE_BACK, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
+                KEY_PRESS_EVENT_TIMEOUT);
+    }
+
+    /**
+     * Simulates a short press on the HOME button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressHome() {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
+                KeyEvent.KEYCODE_HOME, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
+                KEY_PRESS_EVENT_TIMEOUT);
+    }
+
+    /**
+     * Simulates a short press on the SEARCH button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressSearch() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_SEARCH);
+    }
+
+    /**
+     * Simulates a short press on the CENTER button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDPadCenter() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DPAD_CENTER);
+    }
+
+    /**
+     * Simulates a short press on the DOWN button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDPadDown() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN);
+    }
+
+    /**
+     * Simulates a short press on the UP button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDPadUp() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DPAD_UP);
+    }
+
+    /**
+     * Simulates a short press on the LEFT button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDPadLeft() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DPAD_LEFT);
+    }
+
+    /**
+     * Simulates a short press on the RIGHT button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDPadRight() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT);
+    }
+
+    /**
+     * Simulates a short press on the DELETE key.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDelete() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DEL);
+    }
+
+    /**
+     * Simulates a short press on the ENTER key.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressEnter() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_ENTER);
+    }
+
+    /**
+     * Simulates a short press using a key code.
+     *
+     * See {@link KeyEvent}
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressKeyCode(int keyCode) {
+        Tracer.trace(keyCode);
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().sendKey(keyCode, 0);
+    }
+
+    /**
+     * Simulates a short press using a key code.
+     *
+     * See {@link KeyEvent}.
+     * @param keyCode the key code of the event.
+     * @param metaState an integer in which each bit set to 1 represents a pressed meta key
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressKeyCode(int keyCode, int metaState) {
+        Tracer.trace(keyCode, metaState);
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().sendKey(keyCode, metaState);
+    }
+
+    /**
+     * Simulates a short press on the Recent Apps button.
+     *
+     * @return true if successful, else return false
+     * @throws RemoteException
+     * @since API Level 16
+     */
+    public boolean pressRecentApps() throws RemoteException {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().toggleRecentApps();
+    }
+
+    /**
+     * Opens the notification shade.
+     *
+     * @return true if successful, else return false
+     * @since API Level 18
+     */
+    public boolean openNotification() {
+        Tracer.trace();
+        waitForIdle();
+        return  getAutomatorBridge().getInteractionController().openNotification();
+    }
+
+    /**
+     * Opens the Quick Settings shade.
+     *
+     * @return true if successful, else return false
+     * @since API Level 18
+     */
+    public boolean openQuickSettings() {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().openQuickSettings();
+    }
+
+    /**
+     * Gets the width of the display, in pixels. The width and height details
+     * are reported based on the current orientation of the display.
+     * @return width in pixels or zero on failure
+     * @since API Level 16
+     */
+    public int getDisplayWidth() {
+        Tracer.trace();
+        Display display = getAutomatorBridge().getDefaultDisplay();
+        Point p = new Point();
+        display.getSize(p);
+        return p.x;
+    }
+
+    /**
+     * Gets the height of the display, in pixels. The size is adjusted based
+     * on the current orientation of the display.
+     * @return height in pixels or zero on failure
+     * @since API Level 16
+     */
+    public int getDisplayHeight() {
+        Tracer.trace();
+        Display display = getAutomatorBridge().getDefaultDisplay();
+        Point p = new Point();
+        display.getSize(p);
+        return p.y;
+    }
+
+    /**
+     * Perform a click at arbitrary coordinates specified by the user
+     *
+     * @param x coordinate
+     * @param y coordinate
+     * @return true if the click succeeded else false
+     * @since API Level 16
+     */
+    public boolean click(int x, int y) {
+        Tracer.trace(x, y);
+        if (x >= getDisplayWidth() || y >= getDisplayHeight()) {
+            return (false);
+        }
+        return getAutomatorBridge().getInteractionController().clickNoSync(x, y);
+    }
+
+    /**
+     * Performs a swipe from one coordinate to another using the number of steps
+     * to determine smoothness and speed. Each step execution is throttled to 5ms
+     * per step. So for a 100 steps, the swipe will take about 1/2 second to complete.
+     *
+     * @param startX
+     * @param startY
+     * @param endX
+     * @param endY
+     * @param steps is the number of move steps sent to the system
+     * @return false if the operation fails or the coordinates are invalid
+     * @since API Level 16
+     */
+    public boolean swipe(int startX, int startY, int endX, int endY, int steps) {
+        Tracer.trace(startX, startY, endX, endY, steps);
+        return getAutomatorBridge().getInteractionController()
+                .swipe(startX, startY, endX, endY, steps);
+    }
+
+    /**
+     * Performs a swipe from one coordinate to another coordinate. You can control
+     * the smoothness and speed of the swipe by specifying the number of steps.
+     * Each step execution is throttled to 5 milliseconds per step, so for a 100
+     * steps, the swipe will take around 0.5 seconds to complete.
+     *
+     * @param startX X-axis value for the starting coordinate
+     * @param startY Y-axis value for the starting coordinate
+     * @param endX X-axis value for the ending coordinate
+     * @param endY Y-axis value for the ending coordinate
+     * @param steps is the number of steps for the swipe action
+     * @return true if swipe is performed, false if the operation fails 
+     * or the coordinates are invalid
+     * @since API Level 18
+     */
+    public boolean drag(int startX, int startY, int endX, int endY, int steps) {
+        Tracer.trace(startX, startY, endX, endY, steps);
+        return getAutomatorBridge().getInteractionController()
+                .swipe(startX, startY, endX, endY, steps, true);
+    }
+
+    /**
+     * Performs a swipe between points in the Point array. Each step execution is throttled
+     * to 5ms per step. So for a 100 steps, the swipe will take about 1/2 second to complete
+     *
+     * @param segments is Point array containing at least one Point object
+     * @param segmentSteps steps to inject between two Points
+     * @return true on success
+     * @since API Level 16
+     */
+    public boolean swipe(Point[] segments, int segmentSteps) {
+        Tracer.trace(segments, segmentSteps);
+        return getAutomatorBridge().getInteractionController().swipe(segments, segmentSteps);
+    }
+
+    /**
+     * Waits for the current application to idle.
+     * Default wait timeout is 10 seconds
+     * @since API Level 16
+     */
+    public void waitForIdle() {
+        Tracer.trace();
+        waitForIdle(Configurator.getInstance().getWaitForIdleTimeout());
+    }
+
+    /**
+     * Waits for the current application to idle.
+     * @param timeout in milliseconds
+     * @since API Level 16
+     */
+    public void waitForIdle(long timeout) {
+        Tracer.trace(timeout);
+        getAutomatorBridge().waitForIdle(timeout);
+    }
+
+    /**
+     * Retrieves the last activity to report accessibility events.
+     * @deprecated The results returned should be considered unreliable
+     * @return String name of activity
+     * @since API Level 16
+     */
+    @Deprecated
+    public String getCurrentActivityName() {
+        Tracer.trace();
+        return getAutomatorBridge().getQueryController().getCurrentActivityName();
+    }
+
+    /**
+     * Retrieves the name of the last package to report accessibility events.
+     * @return String name of package
+     * @since API Level 16
+     */
+    public String getCurrentPackageName() {
+        Tracer.trace();
+        return getAutomatorBridge().getQueryController().getCurrentPackageName();
+    }
+
+    /**
+     * Registers a {@link UiWatcher} to run automatically when the testing framework is unable to
+     * find a match using a {@link UiSelector}. See {@link #runWatchers()}
+     *
+     * @param name to register the UiWatcher
+     * @param watcher {@link UiWatcher}
+     * @since API Level 16
+     */
+    public void registerWatcher(String name, UiWatcher watcher) {
+        Tracer.trace(name, watcher);
+        if (mInWatcherContext) {
+            throw new IllegalStateException("Cannot register new watcher from within another");
+        }
+        mWatchers.put(name, watcher);
+    }
+
+    /**
+     * Removes a previously registered {@link UiWatcher}.
+     *
+     * See {@link #registerWatcher(String, UiWatcher)}
+     * @param name used to register the UiWatcher
+     * @since API Level 16
+     */
+    public void removeWatcher(String name) {
+        Tracer.trace(name);
+        if (mInWatcherContext) {
+            throw new IllegalStateException("Cannot remove a watcher from within another");
+        }
+        mWatchers.remove(name);
+    }
+
+    /**
+     * This method forces all registered watchers to run.
+     * See {@link #registerWatcher(String, UiWatcher)}
+     * @since API Level 16
+     */
+    public void runWatchers() {
+        Tracer.trace();
+        if (mInWatcherContext) {
+            return;
+        }
+
+        for (String watcherName : mWatchers.keySet()) {
+            UiWatcher watcher = mWatchers.get(watcherName);
+            if (watcher != null) {
+                try {
+                    mInWatcherContext = true;
+                    if (watcher.checkForCondition()) {
+                        setWatcherTriggered(watcherName);
+                    }
+                } catch (Exception e) {
+                    Log.e(LOG_TAG, "Exceuting watcher: " + watcherName, e);
+                } finally {
+                    mInWatcherContext = false;
+                }
+            }
+        }
+    }
+
+    /**
+     * Resets a {@link UiWatcher} that has been triggered.
+     * If a UiWatcher runs and its {@link UiWatcher#checkForCondition()} call
+     * returned <code>true</code>, then the UiWatcher is considered triggered.
+     * See {@link #registerWatcher(String, UiWatcher)}
+     * @since API Level 16
+     */
+    public void resetWatcherTriggers() {
+        Tracer.trace();
+        mWatchersTriggers.clear();
+    }
+
+    /**
+     * Checks if a specific registered  {@link UiWatcher} has triggered.
+     * See {@link #registerWatcher(String, UiWatcher)}. If a UiWatcher runs and its
+     * {@link UiWatcher#checkForCondition()} call returned <code>true</code>, then
+     * the UiWatcher is considered triggered. This is helpful if a watcher is detecting errors
+     * from ANR or crash dialogs and the test needs to know if a UiWatcher has been triggered.
+     *
+     * @param watcherName
+     * @return true if triggered else false
+     * @since API Level 16
+     */
+    public boolean hasWatcherTriggered(String watcherName) {
+        Tracer.trace(watcherName);
+        return mWatchersTriggers.contains(watcherName);
+    }
+
+    /**
+     * Checks if any registered {@link UiWatcher} have triggered.
+     *
+     * See {@link #registerWatcher(String, UiWatcher)}
+     * See {@link #hasWatcherTriggered(String)}
+     * @since API Level 16
+     */
+    public boolean hasAnyWatcherTriggered() {
+        Tracer.trace();
+        return mWatchersTriggers.size() > 0;
+    }
+
+    /**
+     * Used internally by this class to set a {@link UiWatcher} state as triggered.
+     * @param watcherName
+     */
+    private void setWatcherTriggered(String watcherName) {
+        Tracer.trace(watcherName);
+        if (!hasWatcherTriggered(watcherName)) {
+            mWatchersTriggers.add(watcherName);
+        }
+    }
+
+    /**
+     * Check if the device is in its natural orientation. This is determined by checking if the
+     * orientation is at 0 or 180 degrees.
+     * @return true if it is in natural orientation
+     * @since API Level 17
+     */
+    public boolean isNaturalOrientation() {
+        Tracer.trace();
+        waitForIdle();
+        int ret = getAutomatorBridge().getRotation();
+        return ret == UiAutomation.ROTATION_FREEZE_0 ||
+                ret == UiAutomation.ROTATION_FREEZE_180;
+    }
+
+    /**
+     * Returns the current rotation of the display, as defined in {@link Surface}
+     * @since API Level 17
+     */
+    public int getDisplayRotation() {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getRotation();
+    }
+
+    /**
+     * Disables the sensors and freezes the device rotation at its
+     * current rotation state.
+     * @throws RemoteException
+     * @since API Level 16
+     */
+    public void freezeRotation() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().freezeRotation();
+    }
+
+    /**
+     * Re-enables the sensors and un-freezes the device rotation allowing its contents
+     * to rotate with the device physical rotation. During a test execution, it is best to
+     * keep the device frozen in a specific orientation until the test case execution has completed.
+     * @throws RemoteException
+     */
+    public void unfreezeRotation() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().unfreezeRotation();
+    }
+
+    /**
+     * Simulates orienting the device to the left and also freezes rotation
+     * by disabling the sensors.
+     *
+     * If you want to un-freeze the rotation and re-enable the sensors
+     * see {@link #unfreezeRotation()}.
+     * @throws RemoteException
+     * @since API Level 17
+     */
+    public void setOrientationLeft() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().setRotationLeft();
+        waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
+    }
+
+    /**
+     * Simulates orienting the device to the right and also freezes rotation
+     * by disabling the sensors.
+     *
+     * If you want to un-freeze the rotation and re-enable the sensors
+     * see {@link #unfreezeRotation()}.
+     * @throws RemoteException
+     * @since API Level 17
+     */
+    public void setOrientationRight() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().setRotationRight();
+        waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
+    }
+
+    /**
+     * Simulates orienting the device into its natural orientation and also freezes rotation
+     * by disabling the sensors.
+     *
+     * If you want to un-freeze the rotation and re-enable the sensors
+     * see {@link #unfreezeRotation()}.
+     * @throws RemoteException
+     * @since API Level 17
+     */
+    public void setOrientationNatural() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().setRotationNatural();
+        waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
+    }
+
+    /**
+     * This method simulates pressing the power button if the screen is OFF else
+     * it does nothing if the screen is already ON.
+     *
+     * If the screen was OFF and it just got turned ON, this method will insert a 500ms delay
+     * to allow the device time to wake up and accept input.
+     * @throws RemoteException
+     * @since API Level 16
+     */
+    public void wakeUp() throws RemoteException {
+        Tracer.trace();
+        if(getAutomatorBridge().getInteractionController().wakeDevice()) {
+            // sync delay to allow the window manager to start accepting input
+            // after the device is awakened.
+            SystemClock.sleep(500);
+        }
+    }
+
+    /**
+     * Checks the power manager if the screen is ON.
+     *
+     * @return true if the screen is ON else false
+     * @throws RemoteException
+     * @since API Level 16
+     */
+    public boolean isScreenOn() throws RemoteException {
+        Tracer.trace();
+        return getAutomatorBridge().getInteractionController().isScreenOn();
+    }
+
+    /**
+     * This method simply presses the power button if the screen is ON else
+     * it does nothing if the screen is already OFF.
+     *
+     * @throws RemoteException
+     * @since API Level 16
+     */
+    public void sleep() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().sleepDevice();
+    }
+
+    /**
+     * Helper method used for debugging to dump the current window's layout hierarchy.
+     * The file root location is /data/local/tmp
+     *
+     * @param fileName
+     * @since API Level 16
+     */
+    public void dumpWindowHierarchy(String fileName) {
+        Tracer.trace(fileName);
+        AccessibilityNodeInfo root =
+                getAutomatorBridge().getQueryController().getAccessibilityRootNode();
+        if(root != null) {
+            Display display = getAutomatorBridge().getDefaultDisplay();
+            Point size = new Point();
+            display.getSize(size);
+            AccessibilityNodeInfoDumper.dumpWindowToFile(root,
+                    new File(new File(Environment.getDataDirectory(), "local/tmp"), fileName),
+                    display.getRotation(), size.x, size.y);
+        }
+    }
+
+    /**
+     * Waits for a window content update event to occur.
+     *
+     * If a package name for the window is specified, but the current window
+     * does not have the same package name, the function returns immediately.
+     *
+     * @param packageName the specified window package name (can be <code>null</code>).
+     *        If <code>null</code>, a window update from any front-end window will end the wait
+     * @param timeout the timeout for the wait
+     *
+     * @return true if a window update occurred, false if timeout has elapsed or if the current
+     *         window does not have the specified package name
+     * @since API Level 16
+     */
+    public boolean waitForWindowUpdate(final String packageName, long timeout) {
+        Tracer.trace(packageName, timeout);
+        if (packageName != null) {
+            if (!packageName.equals(getCurrentPackageName())) {
+                return false;
+            }
+        }
+        Runnable emptyRunnable = new Runnable() {
+            @Override
+            public void run() {
+            }
+        };
+        AccessibilityEventFilter checkWindowUpdate = new AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent t) {
+                if (t.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
+                    return packageName == null || packageName.equals(t.getPackageName());
+                }
+                return false;
+            }
+        };
+        try {
+            getAutomatorBridge().executeCommandAndWaitForAccessibilityEvent(
+                    emptyRunnable, checkWindowUpdate, timeout);
+        } catch (TimeoutException e) {
+            return false;
+        } catch (Exception e) {
+            Log.e(LOG_TAG, "waitForWindowUpdate: general exception from bridge", e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Take a screenshot of current window and store it as PNG
+     *
+     * Default scale of 1.0f (original size) and 90% quality is used
+     * The screenshot is adjusted per screen rotation
+     *
+     * @param storePath where the PNG should be written to
+     * @return true if screen shot is created successfully, false otherwise
+     * @since API Level 17
+     */
+    public boolean takeScreenshot(File storePath) {
+        Tracer.trace(storePath);
+        return takeScreenshot(storePath, 1.0f, 90);
+    }
+
+    /**
+     * Take a screenshot of current window and store it as PNG
+     *
+     * The screenshot is adjusted per screen rotation
+     *
+     * @param storePath where the PNG should be written to
+     * @param scale scale the screenshot down if needed; 1.0f for original size
+     * @param quality quality of the PNG compression; range: 0-100
+     * @return true if screen shot is created successfully, false otherwise
+     * @since API Level 17
+     */
+    public boolean takeScreenshot(File storePath, float scale, int quality) {
+        Tracer.trace(storePath, scale, quality);
+        return getAutomatorBridge().takeScreenshot(storePath, quality);
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/UiObject.java b/library/core-src/com/android/uiautomator/core/UiObject.java
new file mode 100644
index 0000000..4bb99cd
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/UiObject.java
@@ -0,0 +1,1083 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent.PointerCoords;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+/**
+ * A UiObject is a representation of a view. It is not in any way directly bound to a
+ * view as an object reference. A UiObject contains information to help it
+ * locate a matching view at runtime based on the {@link UiSelector} properties specified in
+ * its constructor. Once you create an instance of a UiObject, it can
+ * be reused for different views that match the selector criteria.
+ * @since API Level 16
+ */
+public class UiObject {
+    private static final String LOG_TAG = UiObject.class.getSimpleName();
+    /**
+     * @since API Level 16
+     * @deprecated use {@link Configurator#setWaitForSelectorTimeout(long)}
+     **/
+    @Deprecated
+    protected static final long WAIT_FOR_SELECTOR_TIMEOUT = 10 * 1000;
+    /**
+     * @since API Level 16
+     **/
+    protected static final long WAIT_FOR_SELECTOR_POLL = 1000;
+    // set a default timeout to 5.5s, since ANR threshold is 5s
+    /**
+     * @since API Level 16
+     **/
+    protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500;
+    /**
+     * @since API Level 16
+     **/
+    protected static final int SWIPE_MARGIN_LIMIT = 5;
+    /**
+     * @since API Level 17
+     * @deprecated use {@link Configurator#setScrollAcknowledgmentTimeout(long)}
+     **/
+    @Deprecated
+    protected static final long WAIT_FOR_EVENT_TMEOUT = 3 * 1000;
+    /**
+     * @since API Level 18
+     **/
+    protected static final int FINGER_TOUCH_HALF_WIDTH = 20;
+
+    private final UiSelector mSelector;
+
+    private final Configurator mConfig = Configurator.getInstance();
+
+    /**
+     * Constructs a UiObject to represent a view that matches the specified
+     * selector criteria.
+     * @param selector
+     * @since API Level 16
+     */
+    public UiObject(UiSelector selector) {
+        mSelector = selector;
+    }
+
+    /**
+     * Debugging helper. A test can dump the properties of a selector as a string
+     * to its logs if needed. <code>getSelector().toString();</code>
+     *
+     * @return {@link UiSelector}
+     * @since API Level 16
+     */
+    public final UiSelector getSelector() {
+        Tracer.trace();
+        return new UiSelector(mSelector);
+    }
+
+    /**
+     * Retrieves the {@link QueryController} to translate a {@link UiSelector} selector
+     * into an {@link AccessibilityNodeInfo}.
+     *
+     * @return {@link QueryController}
+     */
+    QueryController getQueryController() {
+        return UiDevice.getInstance().getAutomatorBridge().getQueryController();
+    }
+
+    /**
+     * Retrieves the {@link InteractionController} to perform finger actions such as tapping,
+     * swiping, or entering text.
+     *
+     * @return {@link InteractionController}
+     */
+    InteractionController getInteractionController() {
+        return UiDevice.getInstance().getAutomatorBridge().getInteractionController();
+    }
+
+    /**
+     * Creates a new UiObject for a child view that is under the present UiObject.
+     *
+     * @param selector for child view to match
+     * @return a new UiObject representing the child view
+     * @since API Level 16
+     */
+    public UiObject getChild(UiSelector selector) throws UiObjectNotFoundException {
+        Tracer.trace(selector);
+        return new UiObject(getSelector().childSelector(selector));
+    }
+
+    /**
+     * Creates a new UiObject for a sibling view or a child of the sibling view, 
+     * relative to the present UiObject.
+     *
+     * @param selector for a sibling view or children of the sibling view
+     * @return a new UiObject representing the matched view
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public UiObject getFromParent(UiSelector selector) throws UiObjectNotFoundException {
+        Tracer.trace(selector);
+        return new UiObject(getSelector().fromParent(selector));
+    }
+
+    /**
+     * Counts the child views immediately under the present UiObject.
+     *
+     * @return the count of child views.
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public int getChildCount() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.getChildCount();
+    }
+
+    /**
+     * Finds a matching UI element in the accessibility hierarchy, by
+     * using the selector for this UiObject.
+     *
+     * @param timeout in milliseconds
+     * @return AccessibilityNodeInfo if found else null
+     * @since API Level 16
+     */
+    protected AccessibilityNodeInfo findAccessibilityNodeInfo(long timeout) {
+        AccessibilityNodeInfo node = null;
+        long startMills = SystemClock.uptimeMillis();
+        long currentMills = 0;
+        while (currentMills <= timeout) {
+            node = getQueryController().findAccessibilityNodeInfo(getSelector());
+            if (node != null) {
+                break;
+            } else {
+                // does nothing if we're reentering another runWatchers()
+                UiDevice.getInstance().runWatchers();
+            }
+            currentMills = SystemClock.uptimeMillis() - startMills;
+            if(timeout > 0) {
+                SystemClock.sleep(WAIT_FOR_SELECTOR_POLL);
+            }
+        }
+        return node;
+    }
+
+    /**
+     * Drags this object to a destination UiObject.
+     * The number of steps specified in your input parameter can influence the
+     * drag speed, and varying speeds may impact the results. Consider
+     * evaluating different speeds when using this method in your tests.
+     *
+     * @param destObj the destination UiObject.
+     * @param steps usually 40 steps. You can increase or decrease the steps to change the speed.
+     * @return true if successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 18
+     */
+    public boolean dragTo(UiObject destObj, int steps) throws UiObjectNotFoundException {
+        Rect srcRect = getVisibleBounds();
+        Rect dstRect = destObj.getVisibleBounds();
+        return getInteractionController().swipe(srcRect.centerX(), srcRect.centerY(),
+                dstRect.centerX(), dstRect.centerY(), steps, true);
+    }
+
+    /**
+     * Drags this object to arbitrary coordinates.
+     * The number of steps specified in your input parameter can influence the
+     * drag speed, and varying speeds may impact the results. Consider
+     * evaluating different speeds when using this method in your tests.
+     *
+     * @param destX the X-axis coordinate.
+     * @param destY the Y-axis coordinate.
+     * @param steps usually 40 steps. You can increase or decrease the steps to change the speed.
+     * @return true if successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 18
+     */
+    public boolean dragTo(int destX, int destY, int steps) throws UiObjectNotFoundException {
+        Rect srcRect = getVisibleBounds();
+        return getInteractionController().swipe(srcRect.centerX(), srcRect.centerY(), destX, destY,
+                steps, true);
+    }
+
+    /**
+     * Performs the swipe up action on the UiObject. 
+     * See also:
+     * <ul>
+     * <li>{@link UiScrollable#scrollToBeginning(int)}</li>
+     * <li>{@link UiScrollable#scrollToEnd(int)}</li>
+     * <li>{@link UiScrollable#scrollBackward()}</li>
+     * <li>{@link UiScrollable#scrollForward()}</li>
+     * </ul>
+     *
+     * @param steps indicates the number of injected move steps into the system. Steps are
+     * injected about 5ms apart. So a 100 steps may take about 1/2 second to complete.
+     * @return true of successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean swipeUp(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Rect rect = getVisibleBounds();
+        if(rect.height() <= SWIPE_MARGIN_LIMIT * 2)
+            return false; // too small to swipe
+        return getInteractionController().swipe(rect.centerX(),
+                rect.bottom - SWIPE_MARGIN_LIMIT, rect.centerX(), rect.top + SWIPE_MARGIN_LIMIT,
+                steps);
+    }
+
+    /**
+     * Performs the swipe down action on the UiObject. 
+     * The swipe gesture can be performed over any surface. The targeted
+     * UI element does not need to be scrollable.
+     * See also:
+     * <ul>
+     * <li>{@link UiScrollable#scrollToBeginning(int)}</li>
+     * <li>{@link UiScrollable#scrollToEnd(int)}</li>
+     * <li>{@link UiScrollable#scrollBackward()}</li>
+     * <li>{@link UiScrollable#scrollForward()}</li>
+     * </ul>
+     *
+     * @param steps indicates the number of injected move steps into the system. Steps are
+     * injected about 5ms apart. So a 100 steps may take about 1/2 second to complete.
+     * @return true if successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean swipeDown(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Rect rect = getVisibleBounds();
+        if(rect.height() <= SWIPE_MARGIN_LIMIT * 2)
+            return false; // too small to swipe
+        return getInteractionController().swipe(rect.centerX(),
+                rect.top + SWIPE_MARGIN_LIMIT, rect.centerX(),
+                rect.bottom - SWIPE_MARGIN_LIMIT, steps);
+    }
+
+    /**
+     * Performs the swipe left action on the UiObject. 
+     * The swipe gesture can be performed over any surface. The targeted
+     * UI element does not need to be scrollable.
+     * See also:
+     * <ul>
+     * <li>{@link UiScrollable#scrollToBeginning(int)}</li>
+     * <li>{@link UiScrollable#scrollToEnd(int)}</li>
+     * <li>{@link UiScrollable#scrollBackward()}</li>
+     * <li>{@link UiScrollable#scrollForward()}</li>
+     * </ul>
+     *
+     * @param steps indicates the number of injected move steps into the system. Steps are
+     * injected about 5ms apart. So a 100 steps may take about 1/2 second to complete.
+     * @return true if successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean swipeLeft(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Rect rect = getVisibleBounds();
+        if(rect.width() <= SWIPE_MARGIN_LIMIT * 2)
+            return false; // too small to swipe
+        return getInteractionController().swipe(rect.right - SWIPE_MARGIN_LIMIT,
+                rect.centerY(), rect.left + SWIPE_MARGIN_LIMIT, rect.centerY(), steps);
+    }
+
+    /**
+     * Performs the swipe right action on the UiObject. 
+     * The swipe gesture can be performed over any surface. The targeted
+     * UI element does not need to be scrollable.
+     * See also:
+     * <ul>
+     * <li>{@link UiScrollable#scrollToBeginning(int)}</li>
+     * <li>{@link UiScrollable#scrollToEnd(int)}</li>
+     * <li>{@link UiScrollable#scrollBackward()}</li>
+     * <li>{@link UiScrollable#scrollForward()}</li>
+     * </ul>
+     *
+     * @param steps indicates the number of injected move steps into the system. Steps are
+     * injected about 5ms apart. So a 100 steps may take about 1/2 second to complete.
+     * @return true if successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean swipeRight(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Rect rect = getVisibleBounds();
+        if(rect.width() <= SWIPE_MARGIN_LIMIT * 2)
+            return false; // too small to swipe
+        return getInteractionController().swipe(rect.left + SWIPE_MARGIN_LIMIT,
+                rect.centerY(), rect.right - SWIPE_MARGIN_LIMIT, rect.centerY(), steps);
+    }
+
+    /**
+     * Finds the visible bounds of a partially visible UI element
+     *
+     * @param node
+     * @return null if node is null, else a Rect containing visible bounds
+     */
+    private Rect getVisibleBounds(AccessibilityNodeInfo node) {
+        if (node == null) {
+            return null;
+        }
+
+        // targeted node's bounds
+        int w = UiDevice.getInstance().getDisplayWidth();
+        int h = UiDevice.getInstance().getDisplayHeight();
+        Rect nodeRect = AccessibilityNodeInfoHelper.getVisibleBoundsInScreen(node, w, h);
+
+        // is the targeted node within a scrollable container?
+        AccessibilityNodeInfo scrollableParentNode = getScrollableParent(node);
+        if(scrollableParentNode == null) {
+            // nothing to adjust for so return the node's Rect as is
+            return nodeRect;
+        }
+
+        // Scrollable parent's visible bounds
+        Rect parentRect = AccessibilityNodeInfoHelper
+                .getVisibleBoundsInScreen(scrollableParentNode, w, h);
+        // adjust for partial clipping of targeted by parent node if required
+        nodeRect.intersect(parentRect);
+        return nodeRect;
+    }
+
+    /**
+     * Walks up the layout hierarchy to find a scrollable parent. A scrollable parent
+     * indicates that this node might be in a container where it is partially
+     * visible due to scrolling. In this case, its clickable center might not be visible and
+     * the click coordinates should be adjusted.
+     *
+     * @param node
+     * @return The accessibility node info.
+     */
+    private AccessibilityNodeInfo getScrollableParent(AccessibilityNodeInfo node) {
+        AccessibilityNodeInfo parent = node;
+        while(parent != null) {
+            parent = parent.getParent();
+            if (parent != null && parent.isScrollable()) {
+                return parent;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Performs a click at the center of the visible bounds of the UI element represented
+     * by this UiObject.
+     *
+     * @return true id successful else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean click() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().clickAndSync(rect.centerX(), rect.centerY(),
+                mConfig.getActionAcknowledgmentTimeout());
+    }
+
+    /**
+     * Waits for window transitions that would typically take longer than the
+     * usual default timeouts.
+     * See {@link #clickAndWaitForNewWindow(long)}
+     *
+     * @return true if the event was triggered, else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean clickAndWaitForNewWindow() throws UiObjectNotFoundException {
+        Tracer.trace();
+        return clickAndWaitForNewWindow(WAIT_FOR_WINDOW_TMEOUT);
+    }
+
+    /**
+     * Performs a click at the center of the visible bounds of the UI element represented
+     * by this UiObject and waits for window transitions.
+     *
+     * This method differ from {@link UiObject#click()} only in that this method waits for a
+     * a new window transition as a result of the click. Some examples of a window transition:
+     * <li>launching a new activity</li>
+     * <li>bringing up a pop-up menu</li>
+     * <li>bringing up a dialog</li>
+     *
+     * @param timeout timeout before giving up on waiting for a new window
+     * @return true if the event was triggered, else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean clickAndWaitForNewWindow(long timeout) throws UiObjectNotFoundException {
+        Tracer.trace(timeout);
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().clickAndWaitForNewWindow(rect.centerX(), rect.centerY(),
+                mConfig.getActionAcknowledgmentTimeout());
+    }
+
+    /**
+     * Clicks the top and left corner of the UI element
+     *
+     * @return true on success
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean clickTopLeft() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().clickNoSync(rect.left + 5, rect.top + 5);
+    }
+
+    /**
+     * Long clicks bottom and right corner of the UI element
+     *
+     * @return true if operation was successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean longClickBottomRight() throws UiObjectNotFoundException  {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().longTapNoSync(rect.right - 5, rect.bottom - 5);
+    }
+
+    /**
+     * Clicks the bottom and right corner of the UI element
+     *
+     * @return true on success
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean clickBottomRight() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().clickNoSync(rect.right - 5, rect.bottom - 5);
+    }
+
+    /**
+     * Long clicks the center of the visible bounds of the UI element
+     *
+     * @return true if operation was successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean longClick() throws UiObjectNotFoundException  {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().longTapNoSync(rect.centerX(), rect.centerY());
+    }
+
+    /**
+     * Long clicks on the top and left corner of the UI element
+     *
+     * @return true if operation was successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean longClickTopLeft() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().longTapNoSync(rect.left + 5, rect.top + 5);
+    }
+
+    /**
+     * Reads the <code>text</code> property of the UI element
+     *
+     * @return text value of the current node represented by this UiObject
+     * @throws UiObjectNotFoundException if no match could be found
+     * @since API Level 16
+     */
+    public String getText() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        String retVal = safeStringReturn(node.getText());
+        Log.d(LOG_TAG, String.format("getText() = %s", retVal));
+        return retVal;
+    }
+
+    /**
+     * Retrieves the <code>className</code> property of the UI element.
+     *
+     * @return class name of the current node represented by this UiObject
+     * @throws UiObjectNotFoundException if no match was found
+     * @since API Level 18
+     */
+    public String getClassName() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        String retVal = safeStringReturn(node.getClassName());
+        Log.d(LOG_TAG, String.format("getClassName() = %s", retVal));
+        return retVal;
+    }
+
+    /**
+     * Reads the <code>content_desc</code> property of the UI element
+     *
+     * @return value of node attribute "content_desc"
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public String getContentDescription() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return safeStringReturn(node.getContentDescription());
+    }
+
+    /**
+     * Sets the text in an editable field, after clearing the field's content.
+     *
+     * The {@link UiSelector} selector of this object must reference a UI element that is editable.
+     *
+     * When you call this method, the method first simulates a {@link #click()} on
+     * editable field to set focus. The method then clears the field's contents
+     * and injects your specified text into the field.
+     *
+     * If you want to capture the original contents of the field, call {@link #getText()} first.
+     * You can then modify the text and use this method to update the field.
+     *
+     * @param text string to set
+     * @return true if operation is successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean setText(String text) throws UiObjectNotFoundException {
+        Tracer.trace(text);
+        clearTextField();
+        return getInteractionController().sendText(text);
+    }
+
+    /**
+     * Clears the existing text contents in an editable field.
+     *
+     * The {@link UiSelector} of this object must reference a UI element that is editable.
+     *
+     * When you call this method, the method first sets focus at the start edge of the field.
+     * The method then simulates a long-press to select the existing text, and deletes the
+     * selected text.
+     *
+     * If a "Select-All" option is displayed, the method will automatically attempt to use it
+     * to ensure full text selection.
+     *
+     * Note that it is possible that not all the text in the field is selected; for example,
+     * if the text contains separators such as spaces, slashes, at symbol etc.
+     * Also, not all editable fields support the long-press functionality.
+     *
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public void clearTextField() throws UiObjectNotFoundException {
+        Tracer.trace();
+        // long click left + center
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        getInteractionController().longTapNoSync(rect.left + 20, rect.centerY());
+        // check if the edit menu is open
+        UiObject selectAll = new UiObject(new UiSelector().descriptionContains("Select all"));
+        if(selectAll.waitForExists(50))
+            selectAll.click();
+        // wait for the selection
+        SystemClock.sleep(250);
+        // delete it
+        getInteractionController().sendKey(KeyEvent.KEYCODE_DEL, 0);
+    }
+
+    /**
+     * Check if the UI element's <code>checked</code> property is currently true
+     *
+     * @return true if it is else false
+     * @since API Level 16
+     */
+    public boolean isChecked() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isChecked();
+    }
+
+    /**
+     * Checks if the UI element's <code>selected</code> property is currently true.
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isSelected() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isSelected();
+    }
+
+    /**
+     * Checks if the UI element's <code>checkable</code> property is currently true.
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isCheckable() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isCheckable();
+    }
+
+    /**
+     * Checks if the UI element's <code>enabled</code> property is currently true.
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isEnabled() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isEnabled();
+    }
+
+    /**
+     * Checks if the UI element's <code>clickable</code> property is currently true.
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isClickable() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isClickable();
+    }
+
+    /**
+     * Check if the UI element's <code>focused</code> property is currently true
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isFocused() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isFocused();
+    }
+
+    /**
+     * Check if the UI element's <code>focusable</code> property is currently true.
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isFocusable() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isFocusable();
+    }
+
+    /**
+     * Check if the view's <code>scrollable</code> property is currently true
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isScrollable() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isScrollable();
+    }
+
+    /**
+     * Check if the view's <code>long-clickable</code> property is currently true
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isLongClickable() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isLongClickable();
+    }
+
+    /**
+     * Reads the view's <code>package</code> property
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public String getPackageName() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return safeStringReturn(node.getPackageName());
+    }
+
+    /**
+     * Returns the visible bounds of the view.
+     *
+     * If a portion of the view is visible, only the bounds of the visible portion are
+     * reported.
+     *
+     * @return Rect
+     * @throws UiObjectNotFoundException
+     * @see {@link #getBounds()}
+     * @since API Level 17
+     */
+    public Rect getVisibleBounds() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return getVisibleBounds(node);
+    }
+
+    /**
+     * Returns the view's <code>bounds</code> property. See {@link #getVisibleBounds()}
+     *
+     * @return Rect
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public Rect getBounds() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect nodeRect = new Rect();
+        node.getBoundsInScreen(nodeRect);
+
+        return nodeRect;
+    }
+
+    /**
+     * Waits a specified length of time for a view to become visible.
+     *
+     * This method waits until the view becomes visible on the display, or
+     * until the timeout has elapsed. You can use this method in situations where
+     * the content that you want to select is not immediately displayed.
+     *
+     * @param timeout the amount of time to wait (in milliseconds)
+     * @return true if the view is displayed, else false if timeout elapsed while waiting
+     * @since API Level 16
+     */
+    public boolean waitForExists(long timeout) {
+        Tracer.trace(timeout);
+        if(findAccessibilityNodeInfo(timeout) != null) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Waits a specified length of time for a view to become undetectable.
+     *
+     * This method waits until a view is no longer matchable, or until the
+     * timeout has elapsed.
+     *
+     * A view becomes undetectable when the {@link UiSelector} of the object is
+     * unable to find a match because the element has either changed its state or is no
+     * longer displayed.
+     *
+     * You can use this method when attempting to wait for some long operation
+     * to compete, such as downloading a large file or connecting to a remote server.
+     *
+     * @param timeout time to wait (in milliseconds)
+     * @return true if the element is gone before timeout elapsed, else false if timeout elapsed
+     * but a matching element is still found.
+     * @since API Level 16
+     */
+    public boolean waitUntilGone(long timeout) {
+        Tracer.trace(timeout);
+        long startMills = SystemClock.uptimeMillis();
+        long currentMills = 0;
+        while (currentMills <= timeout) {
+            if(findAccessibilityNodeInfo(0) == null)
+                return true;
+            currentMills = SystemClock.uptimeMillis() - startMills;
+            if(timeout > 0)
+                SystemClock.sleep(WAIT_FOR_SELECTOR_POLL);
+        }
+        return false;
+    }
+
+    /**
+     * Check if view exists.
+     *
+     * This methods performs a {@link #waitForExists(long)} with zero timeout. This
+     * basically returns immediately whether the view represented by this UiObject
+     * exists or not. If you need to wait longer for this view, then see
+     * {@link #waitForExists(long)}.
+     *
+     * @return true if the view represented by this UiObject does exist
+     * @since API Level 16
+     */
+    public boolean exists() {
+        Tracer.trace();
+        return waitForExists(0);
+    }
+
+    private String safeStringReturn(CharSequence cs) {
+        if(cs == null)
+            return "";
+        return cs.toString();
+    }
+
+    /**
+     * Performs a two-pointer gesture, where each pointer moves diagonally
+     * opposite across the other, from the center out towards the edges of the
+     * this UiObject.
+     * @param percent percentage of the object's diagonal length for the pinch gesture
+     * @param steps the number of steps for the gesture. Steps are injected 
+     * about 5 milliseconds apart, so 100 steps may take around 0.5 seconds to complete.
+     * @return <code>true</code> if all touch events for this gesture are injected successfully,
+     *         <code>false</code> otherwise
+     * @throws UiObjectNotFoundException
+     * @since API Level 18
+     */
+    public boolean pinchOut(int percent, int steps) throws UiObjectNotFoundException {
+        // make value between 1 and 100
+        percent = (percent < 0) ? 1 : (percent > 100) ? 100 : percent;
+        float percentage = percent / 100f;
+
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if (node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+
+        Rect rect = getVisibleBounds(node);
+        if (rect.width() <= FINGER_TOUCH_HALF_WIDTH * 2)
+            throw new IllegalStateException("Object width is too small for operation");
+
+        // start from the same point at the center of the control
+        Point startPoint1 = new Point(rect.centerX() - FINGER_TOUCH_HALF_WIDTH, rect.centerY());
+        Point startPoint2 = new Point(rect.centerX() + FINGER_TOUCH_HALF_WIDTH, rect.centerY());
+
+        // End at the top-left and bottom-right corners of the control
+        Point endPoint1 = new Point(rect.centerX() - (int)((rect.width()/2) * percentage),
+                rect.centerY());
+        Point endPoint2 = new Point(rect.centerX() + (int)((rect.width()/2) * percentage),
+                rect.centerY());
+
+        return performTwoPointerGesture(startPoint1, startPoint2, endPoint1, endPoint2, steps);
+    }
+
+    /**
+     * Performs a two-pointer gesture, where each pointer moves diagonally
+     * toward the other, from the edges to the center of this UiObject .
+     * @param percent percentage of the object's diagonal length for the pinch gesture
+     * @param steps the number of steps for the gesture. Steps are injected 
+     * about 5 milliseconds apart, so 100 steps may take around 0.5 seconds to complete.
+     * @return <code>true</code> if all touch events for this gesture are injected successfully,
+     *         <code>false</code> otherwise
+     * @throws UiObjectNotFoundException
+     * @since API Level 18
+     */
+    public boolean pinchIn(int percent, int steps) throws UiObjectNotFoundException {
+        // make value between 1 and 100
+        percent = (percent < 0) ? 0 : (percent > 100) ? 100 : percent;
+        float percentage = percent / 100f;
+
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if (node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+
+        Rect rect = getVisibleBounds(node);
+        if (rect.width() <= FINGER_TOUCH_HALF_WIDTH * 2)
+            throw new IllegalStateException("Object width is too small for operation");
+
+        Point startPoint1 = new Point(rect.centerX() - (int)((rect.width()/2) * percentage),
+                rect.centerY());
+        Point startPoint2 = new Point(rect.centerX() + (int)((rect.width()/2) * percentage),
+                rect.centerY());
+
+        Point endPoint1 = new Point(rect.centerX() - FINGER_TOUCH_HALF_WIDTH, rect.centerY());
+        Point endPoint2 = new Point(rect.centerX() + FINGER_TOUCH_HALF_WIDTH, rect.centerY());
+
+        return performTwoPointerGesture(startPoint1, startPoint2, endPoint1, endPoint2, steps);
+    }
+
+    /**
+     * Generates a two-pointer gesture with arbitrary starting and ending points.
+     *
+     * @param startPoint1 start point of pointer 1
+     * @param startPoint2 start point of pointer 2
+     * @param endPoint1 end point of pointer 1
+     * @param endPoint2 end point of pointer 2
+     * @param steps the number of steps for the gesture. Steps are injected 
+     * about 5 milliseconds apart, so 100 steps may take around 0.5 seconds to complete.
+     * @return <code>true</code> if all touch events for this gesture are injected successfully,
+     *         <code>false</code> otherwise
+     * @since API Level 18
+     */
+    public boolean performTwoPointerGesture(Point startPoint1, Point startPoint2, Point endPoint1,
+            Point endPoint2, int steps) {
+
+        // avoid a divide by zero
+        if(steps == 0)
+            steps = 1;
+
+        final float stepX1 = (endPoint1.x - startPoint1.x) / steps;
+        final float stepY1 = (endPoint1.y - startPoint1.y) / steps;
+        final float stepX2 = (endPoint2.x - startPoint2.x) / steps;
+        final float stepY2 = (endPoint2.y - startPoint2.y) / steps;
+
+        int eventX1, eventY1, eventX2, eventY2;
+        eventX1 = startPoint1.x;
+        eventY1 = startPoint1.y;
+        eventX2 = startPoint2.x;
+        eventY2 = startPoint2.y;
+
+        // allocate for steps plus first down and last up
+        PointerCoords[] points1 = new PointerCoords[steps + 2];
+        PointerCoords[] points2 = new PointerCoords[steps + 2];
+
+        // Include the first and last touch downs in the arrays of steps
+        for (int i = 0; i < steps + 1; i++) {
+            PointerCoords p1 = new PointerCoords();
+            p1.x = eventX1;
+            p1.y = eventY1;
+            p1.pressure = 1;
+            p1.size = 1;
+            points1[i] = p1;
+
+            PointerCoords p2 = new PointerCoords();
+            p2.x = eventX2;
+            p2.y = eventY2;
+            p2.pressure = 1;
+            p2.size = 1;
+            points2[i] = p2;
+
+            eventX1 += stepX1;
+            eventY1 += stepY1;
+            eventX2 += stepX2;
+            eventY2 += stepY2;
+        }
+
+        // ending pointers coordinates
+        PointerCoords p1 = new PointerCoords();
+        p1.x = endPoint1.x;
+        p1.y = endPoint1.y;
+        p1.pressure = 1;
+        p1.size = 1;
+        points1[steps + 1] = p1;
+
+        PointerCoords p2 = new PointerCoords();
+        p2.x = endPoint2.x;
+        p2.y = endPoint2.y;
+        p2.pressure = 1;
+        p2.size = 1;
+        points2[steps + 1] = p2;
+
+        return performMultiPointerGesture(points1, points2);
+    }
+
+    /**
+     * Performs a multi-touch gesture. You must specify touch coordinates for
+     * at least 2 pointers. Each pointer must have all of its touch steps
+     * defined in an array of {@link PointerCoords}. You can use this method to
+     * specify complex gestures, like circles and irregular shapes, where each
+     * pointer may take a different path.
+     *
+     * To create a single point on a pointer's touch path:
+     * <code>
+     *       PointerCoords p = new PointerCoords();
+     *       p.x = stepX;
+     *       p.y = stepY;
+     *       p.pressure = 1;
+     *       p.size = 1;
+     * </code>
+     * @param touches represents the pointers' paths. Each {@link PointerCoords}
+     * array represents a different pointer. Each {@link PointerCoords} in an
+     * array element represents a touch point on a pointer's path.
+     * @return <code>true</code> if all touch events for this gesture are injected successfully,
+     *         <code>false</code> otherwise
+     * @since API Level 18
+     */
+    public boolean performMultiPointerGesture(PointerCoords[] ...touches) {
+        return getInteractionController().performMultiPointerGesture(touches);
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/UiObjectNotFoundException.java b/library/core-src/com/android/uiautomator/core/UiObjectNotFoundException.java
new file mode 100644
index 0000000..fc0891b
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/UiObjectNotFoundException.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+/**
+ * Generated in test runs when a {@link UiSelector} selector could not be matched
+ * to any UI element displayed.
+ * @since API Level 16
+ */
+public class UiObjectNotFoundException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * @since API Level 16
+     **/
+    public UiObjectNotFoundException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * @since API Level 16
+     **/
+    public UiObjectNotFoundException(String detailMessage, Throwable throwable) {
+        super(detailMessage, throwable);
+    }
+
+    /**
+     * @since API Level 16
+     **/
+    public UiObjectNotFoundException(Throwable throwable) {
+        super(throwable);
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/UiScrollable.java b/library/core-src/com/android/uiautomator/core/UiScrollable.java
new file mode 100644
index 0000000..a8d20c3
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/UiScrollable.java
@@ -0,0 +1,665 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+import android.graphics.Rect;
+import android.util.Log;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+/**
+ * UiScrollable is a {@link UiCollection} and provides support for searching
+ * for items in scrollable layout elements. This class can be used with
+ * horizontally or vertically scrollable controls.
+ * @since API Level 16
+ */
+public class UiScrollable extends UiCollection {
+    private static final String LOG_TAG = UiScrollable.class.getSimpleName();
+
+    // More steps slows the swipe and prevents contents from being flung too far
+    private static final int SCROLL_STEPS = 55;
+
+    private static final int FLING_STEPS = 5;
+
+    // Restrict a swipe's starting and ending points inside a 10% margin of the target
+    private static final double DEFAULT_SWIPE_DEADZONE_PCT = 0.1;
+
+    // Limits the number of swipes/scrolls performed during a search
+    private static int mMaxSearchSwipes = 30;
+
+    // Used in ScrollForward() and ScrollBackward() to determine swipe direction
+    private boolean mIsVerticalList = true;
+
+    private double mSwipeDeadZonePercentage = DEFAULT_SWIPE_DEADZONE_PCT;
+
+    /**
+     * Constructor.
+     *
+     * @param container a {@link UiSelector} selector to identify the scrollable
+     *     layout element.
+     * @since API Level 16
+     */
+    public UiScrollable(UiSelector container) {
+        // wrap the container selector with container so that QueryController can handle
+        // this type of enumeration search accordingly
+        super(container);
+    }
+
+    /**
+     * Set the direction of swipes to be vertical when performing scroll actions.
+     * @return reference to itself
+     * @since API Level 16
+     */
+    public UiScrollable setAsVerticalList() {
+        Tracer.trace();
+        mIsVerticalList = true;
+        return this;
+    }
+
+    /**
+     * Set the direction of swipes to be horizontal when performing scroll actions.
+     * @return reference to itself
+     * @since API Level 16
+     */
+    public UiScrollable setAsHorizontalList() {
+        Tracer.trace();
+        mIsVerticalList = false;
+        return this;
+    }
+
+    /**
+     * Used privately when performing swipe searches to decide if an element has become
+     * visible or not.
+     *
+     * @param selector
+     * @return true if found else false
+     * @since API Level 16
+     */
+    protected boolean exists(UiSelector selector) {
+        if(getQueryController().findAccessibilityNodeInfo(selector) != null) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Searches for a child element in the present scrollable container.
+     * The search first looks for a child element that matches the selector
+     * you provided, then looks for the content-description in its children elements.
+     * If both search conditions are fulfilled, the method returns a {@ link UiObject}
+     * representing the element matching the selector (not the child element in its
+     * subhierarchy containing the content-description). By default, this method performs a
+     * scroll search.
+     * See {@link #getChildByDescription(UiSelector, String, boolean)}
+     *
+     * @param childPattern {@link UiSelector} for a child in a scollable layout element
+     * @param text Content-description to find in the children of 
+     * the <code>childPattern</code> match
+     * @return {@link UiObject} representing the child element that matches the search conditions
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    @Override
+    public UiObject getChildByDescription(UiSelector childPattern, String text)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text);
+        return getChildByDescription(childPattern, text, true);
+    }
+
+    /**
+     * Searches for a child element in the present scrollable container.
+     * The search first looks for a child element that matches the selector
+     * you provided, then looks for the content-description in its children elements.
+     * If both search conditions are fulfilled, the method returns a {@ link UiObject}
+     * representing the element matching the selector (not the child element in its
+     * subhierarchy containing the content-description).
+     *
+     * @param childPattern {@link UiSelector} for a child in a scollable layout element
+     * @param text Content-description to find in the children of 
+     * the <code>childPattern</code> match (may be a partial match)
+     * @param allowScrollSearch set to true if scrolling is allowed
+     * @return {@link UiObject} representing the child element that matches the search conditions
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public UiObject getChildByDescription(UiSelector childPattern, String text,
+            boolean allowScrollSearch) throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text, allowScrollSearch);
+        if (text != null) {
+            if (allowScrollSearch) {
+                scrollIntoView(new UiSelector().descriptionContains(text));
+            }
+            return super.getChildByDescription(childPattern, text);
+        }
+        throw new UiObjectNotFoundException("for description= \"" + text + "\"");
+    }
+
+    /**
+     * Searches for a child element in the present scrollable container that
+     * matches the selector you provided. The search is performed without
+     * scrolling and only on visible elements.
+     *
+     * @param childPattern {@link UiSelector} for a child in a scollable layout element
+     * @param instance int number representing the occurance of 
+     * a <code>childPattern</code> match
+     * @return {@link UiObject} representing the child element that matches the search conditions
+     * @since API Level 16
+     */
+    @Override
+    public UiObject getChildByInstance(UiSelector childPattern, int instance)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, instance);
+        UiSelector patternSelector = UiSelector.patternBuilder(getSelector(),
+                UiSelector.patternBuilder(childPattern).instance(instance));
+        return new UiObject(patternSelector);
+    }
+
+    /**
+     * Searches for a child element in the present scrollable
+     * container. The search first looks for a child element that matches the
+     * selector you provided, then looks for the text in its children elements.
+     * If both search conditions are fulfilled, the method returns a {@ link UiObject}
+     * representing the element matching the selector (not the child element in its
+     * subhierarchy containing the text). By default, this method performs a
+     * scroll search.
+     * See {@link #getChildByText(UiSelector, String, boolean)}
+     *
+     * @param childPattern {@link UiSelector} selector for a child in a scrollable layout element
+     * @param text String to find in the children of the <code>childPattern</code> match
+     * @return {@link UiObject} representing the child element that matches the search conditions
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    @Override
+    public UiObject getChildByText(UiSelector childPattern, String text)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text);
+        return getChildByText(childPattern, text, true);
+    }
+
+    /**
+     * Searches for a child element in the present scrollable container. The
+     * search first looks for a child element that matches the
+     * selector you provided, then looks for the text in its children elements.
+     * If both search conditions are fulfilled, the method returns a {@ link UiObject}
+     * representing the element matching the selector (not the child element in its
+     * subhierarchy containing the text).
+     *
+     * @param childPattern {@link UiSelector} selector for a child in a scrollable layout element
+     * @param text String to find in the children of the <code>childPattern</code> match
+     * @param allowScrollSearch set to true if scrolling is allowed
+     * @return {@link UiObject} representing the child element that matches the search conditions
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public UiObject getChildByText(UiSelector childPattern, String text, boolean allowScrollSearch)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text, allowScrollSearch);
+        if (text != null) {
+            if (allowScrollSearch) {
+                scrollIntoView(new UiSelector().text(text));
+            }
+            return super.getChildByText(childPattern, text);
+        }
+        throw new UiObjectNotFoundException("for text= \"" + text + "\"");
+    }
+
+    /**
+     * Performs a forward scroll action on the scrollable layout element until
+     * the content-description is found, or until swipe attempts have been exhausted.
+     * See {@link #setMaxSearchSwipes(int)}
+     *
+     * @param text content-description to find within the contents of this scrollable layout element.
+     * @return true if item is found; else, false
+     * @since API Level 16
+     */
+    public boolean scrollDescriptionIntoView(String text) throws UiObjectNotFoundException {
+        Tracer.trace(text);
+        return scrollIntoView(new UiSelector().description(text));
+    }
+
+    /**
+     * Perform a forward scroll action to move through the scrollable layout element until
+     * a visible item that matches the {@link UiObject} is found.
+     *
+     * @param obj {@link UiObject}
+     * @return true if the item was found and now is in view else false
+     * @since API Level 16
+     */
+    public boolean scrollIntoView(UiObject obj) throws UiObjectNotFoundException {
+        Tracer.trace(obj.getSelector());
+        return scrollIntoView(obj.getSelector());
+    }
+
+    /**
+     * Perform a scroll forward action to move through the scrollable layout 
+     * element until a visible item that matches the selector is found.
+     *
+     * See {@link #scrollDescriptionIntoView(String)} and {@link #scrollTextIntoView(String)}.
+     *
+     * @param selector {@link UiSelector} selector
+     * @return true if the item was found and now is in view; else, false
+     * @since API Level 16
+     */
+    public boolean scrollIntoView(UiSelector selector) throws UiObjectNotFoundException {
+        Tracer.trace(selector);
+        // if we happen to be on top of the text we want then return here
+        UiSelector childSelector = getSelector().childSelector(selector);
+        if (exists(childSelector)) {
+            return (true);
+        } else {
+            // we will need to reset the search from the beginning to start search
+            scrollToBeginning(mMaxSearchSwipes);
+            if (exists(childSelector)) {
+                return (true);
+            }
+            for (int x = 0; x < mMaxSearchSwipes; x++) {
+                boolean scrolled = scrollForward();
+                if(exists(childSelector)) {
+                    return true;
+                }
+                if (!scrolled) {
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Scrolls forward until the UiObject is fully visible in the scrollable container.
+     * Use this method to make sure that the child item's edges are not offscreen.
+     *
+     * @param childObject {@link UiObject} representing the child element
+     * @return true if the child element is already fully visible, or 
+     * if the method scrolled successfully until the child became fully visible; 
+     * otherwise, false if the attempt to scroll failed.
+     * @throws UiObjectNotFoundException
+     * @hide
+     */
+    public boolean ensureFullyVisible(UiObject childObject) throws UiObjectNotFoundException {
+        Rect actual = childObject.getBounds();
+        Rect visible = childObject.getVisibleBounds();
+        if (visible.width() * visible.height() == actual.width() * actual.height()) {
+            // area match, item fully visible
+            return true;
+        }
+        boolean shouldSwipeForward = false;
+        if (mIsVerticalList) {
+            // if list is vertical, matching top edge implies obscured bottom edge
+            // so we need to scroll list forward
+            shouldSwipeForward = actual.top == visible.top;
+        } else {
+            // if list is horizontal, matching left edge implies obscured right edge,
+            // so we need to scroll list forward
+            shouldSwipeForward = actual.left == visible.left;
+        }
+        if (mIsVerticalList) {
+            if (shouldSwipeForward) {
+                return swipeUp(10);
+            } else {
+                return swipeDown(10);
+            }
+        } else {
+            if (shouldSwipeForward) {
+                return swipeLeft(10);
+            } else {
+                return swipeRight(10);
+            }
+        }
+    }
+
+    /**
+     * Performs a forward scroll action on the scrollable layout element until
+     * the text you provided is visible, or until swipe attempts have been exhausted.
+     * See {@link #setMaxSearchSwipes(int)}
+     *
+     * @param text test to look for
+     * @return true if item is found; else, false
+     * @since API Level 16
+     */
+    public boolean scrollTextIntoView(String text) throws UiObjectNotFoundException {
+        Tracer.trace(text);
+        return scrollIntoView(new UiSelector().text(text));
+    }
+
+    /**
+     * Sets the maximum number of scrolls allowed when performing a
+     * scroll action in search of a child element.
+     * See {@link #getChildByDescription(UiSelector, String)} and
+     * {@link #getChildByText(UiSelector, String)}.
+     *
+     * @param swipes the number of search swipes to perform until giving up
+     * @return reference to itself
+     * @since API Level 16
+     */
+    public UiScrollable setMaxSearchSwipes(int swipes) {
+        Tracer.trace(swipes);
+        mMaxSearchSwipes = swipes;
+        return this;
+    }
+
+    /**
+     * Gets the maximum number of scrolls allowed when performing a
+     * scroll action in search of a child element.
+     * See {@link #getChildByDescription(UiSelector, String)} and
+     * {@link #getChildByText(UiSelector, String)}.
+     *
+     * @return max the number of search swipes to perform until giving up
+     * @since API Level 16
+     */
+    public int getMaxSearchSwipes() {
+        Tracer.trace();
+        return mMaxSearchSwipes;
+    }
+
+    /**
+     * Performs a forward fling with the default number of fling steps (5).
+     * If the swipe direction is set to vertical, then the swipes will be
+     * performed from bottom to top. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * right to left. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @return true if scrolled, false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean flingForward() throws UiObjectNotFoundException {
+        Tracer.trace();
+        return scrollForward(FLING_STEPS);
+    }
+
+    /**
+     * Performs a forward scroll with the default number of scroll steps (55).
+     * If the swipe direction is set to vertical,
+     * then the swipes will be performed from bottom to top. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * right to left. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @return true if scrolled, false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean scrollForward() throws UiObjectNotFoundException {
+        Tracer.trace();
+        return scrollForward(SCROLL_STEPS);
+    }
+
+    /**
+     * Performs a forward scroll. If the swipe direction is set to vertical,
+     * then the swipes will be performed from bottom to top. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * right to left. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @param steps number of steps. Use this to control the speed of the scroll action
+     * @return true if scrolled, false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean scrollForward(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Log.d(LOG_TAG, "scrollForward() on selector = " + getSelector());
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(WAIT_FOR_SELECTOR_TIMEOUT);
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = new Rect();
+        node.getBoundsInScreen(rect);
+
+        int downX = 0;
+        int downY = 0;
+        int upX = 0;
+        int upY = 0;
+
+        // scrolling is by default assumed vertically unless the object is explicitly
+        // set otherwise by setAsHorizontalContainer()
+        if(mIsVerticalList) {
+            int swipeAreaAdjust = (int)(rect.height() * getSwipeDeadZonePercentage());
+            // scroll vertically: swipe down -> up
+            downX = rect.centerX();
+            downY = rect.bottom - swipeAreaAdjust;
+            upX = rect.centerX();
+            upY = rect.top + swipeAreaAdjust;
+        } else {
+            int swipeAreaAdjust = (int)(rect.width() * getSwipeDeadZonePercentage());
+            // scroll horizontally: swipe right -> left
+            // TODO: Assuming device is not in right to left language
+            downX = rect.right - swipeAreaAdjust;
+            downY = rect.centerY();
+            upX = rect.left + swipeAreaAdjust;
+            upY = rect.centerY();
+        }
+        return getInteractionController().scrollSwipe(downX, downY, upX, upY, steps);
+    }
+
+    /**
+     * Performs a backwards fling action with the default number of fling
+     * steps (5). If the swipe direction is set to vertical,
+     * then the swipe will be performed from top to bottom. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * left to right. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @return true if scrolled, and false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean flingBackward() throws UiObjectNotFoundException {
+        Tracer.trace();
+        return scrollBackward(FLING_STEPS);
+    }
+
+    /**
+     * Performs a backward scroll with the default number of scroll steps (55).
+     * If the swipe direction is set to vertical,
+     * then the swipes will be performed from top to bottom. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * left to right. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @return true if scrolled, and false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean scrollBackward() throws UiObjectNotFoundException {
+        Tracer.trace();
+        return scrollBackward(SCROLL_STEPS);
+    }
+
+    /**
+     * Performs a backward scroll. If the swipe direction is set to vertical,
+     * then the swipes will be performed from top to bottom. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * left to right. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @param steps number of steps. Use this to control the speed of the scroll action.
+     * @return true if scrolled, false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean scrollBackward(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Log.d(LOG_TAG, "scrollBackward() on selector = " + getSelector());
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(WAIT_FOR_SELECTOR_TIMEOUT);
+        if (node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = new Rect();
+        node.getBoundsInScreen(rect);
+
+        int downX = 0;
+        int downY = 0;
+        int upX = 0;
+        int upY = 0;
+
+        // scrolling is by default assumed vertically unless the object is explicitly
+        // set otherwise by setAsHorizontalContainer()
+        if(mIsVerticalList) {
+            int swipeAreaAdjust = (int)(rect.height() * getSwipeDeadZonePercentage());
+            Log.d(LOG_TAG, "scrollToBegining() using vertical scroll");
+            // scroll vertically: swipe up -> down
+            downX = rect.centerX();
+            downY = rect.top + swipeAreaAdjust;
+            upX = rect.centerX();
+            upY = rect.bottom - swipeAreaAdjust;
+        } else {
+            int swipeAreaAdjust = (int)(rect.width() * getSwipeDeadZonePercentage());
+            Log.d(LOG_TAG, "scrollToBegining() using hotizontal scroll");
+            // scroll horizontally: swipe left -> right
+            // TODO: Assuming device is not in right to left language
+            downX = rect.left + swipeAreaAdjust;
+            downY = rect.centerY();
+            upX = rect.right - swipeAreaAdjust;
+            upY = rect.centerY();
+        }
+        return getInteractionController().scrollSwipe(downX, downY, upX, upY, steps);
+    }
+
+    /**
+     * Scrolls to the beginning of a scrollable layout element. The beginning
+     * can be at the  top-most edge in the case of vertical controls, or the
+     * left-most edge for horizontal controls. Make sure to take into account
+     * devices configured with right-to-left languages like Arabic and Hebrew.
+     *
+     * @param steps use steps to control the speed, so that it may be a scroll, or fling
+     * @return true on scrolled else false
+     * @since API Level 16
+     */
+    public boolean scrollToBeginning(int maxSwipes, int steps) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes, steps);
+        Log.d(LOG_TAG, "scrollToBeginning() on selector = " + getSelector());
+        // protect against potential hanging and return after preset attempts
+        for(int x = 0; x < maxSwipes; x++) {
+            if(!scrollBackward(steps)) {
+                break;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Scrolls to the beginning of a scrollable layout element. The beginning
+     * can be at the  top-most edge in the case of vertical controls, or the
+     * left-most edge for horizontal controls. Make sure to take into account
+     * devices configured with right-to-left languages like Arabic and Hebrew.
+     *
+     * @param maxSwipes
+     * @return true on scrolled else false
+     * @since API Level 16
+     */
+    public boolean scrollToBeginning(int maxSwipes) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes);
+        return scrollToBeginning(maxSwipes, SCROLL_STEPS);
+    }
+
+    /**
+     * Performs a fling gesture to reach the beginning of a scrollable layout element.
+     * The beginning can be at the  top-most edge in the case of vertical controls, or
+     * the left-most edge for horizontal controls. Make sure to take into
+     * account devices configured with right-to-left languages like Arabic and Hebrew.
+     *
+     * @param maxSwipes
+     * @return true on scrolled else false
+     * @since API Level 16
+     */
+    public boolean flingToBeginning(int maxSwipes) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes);
+        return scrollToBeginning(maxSwipes, FLING_STEPS);
+    }
+
+    /**
+     * Scrolls to the end of a scrollable layout element. The end can be at the
+     * bottom-most edge in the case of vertical controls, or the right-most edge for
+     * horizontal controls. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @param steps use steps to control the speed, so that it may be a scroll, or fling
+     * @return true on scrolled else false
+     * @since API Level 16
+     */
+    public boolean scrollToEnd(int maxSwipes, int steps) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes, steps);
+        // protect against potential hanging and return after preset attempts
+        for(int x = 0; x < maxSwipes; x++) {
+            if(!scrollForward(steps)) {
+                break;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Scrolls to the end of a scrollable layout element. The end can be at the
+     * bottom-most edge in the case of vertical controls, or the right-most edge for
+     * horizontal controls. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @param maxSwipes
+     * @return true on scrolled, else false
+     * @since API Level 16
+     */
+    public boolean scrollToEnd(int maxSwipes) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes);
+        return scrollToEnd(maxSwipes, SCROLL_STEPS);
+    }
+
+    /**
+     * Performs a fling gesture to reach the end of a scrollable layout element.
+     * The end can be at the  bottom-most edge in the case of vertical controls, or
+     * the right-most edge for horizontal controls. Make sure to take into
+     * account devices configured with right-to-left languages like Arabic and Hebrew.
+     *
+     * @param maxSwipes
+     * @return true on scrolled, else false
+     * @since API Level 16
+     */
+    public boolean flingToEnd(int maxSwipes) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes);
+        return scrollToEnd(maxSwipes, FLING_STEPS);
+    }
+
+    /**
+     * Returns the percentage of a widget's size that's considered as a no-touch
+     * zone when swiping. The no-touch zone is set as a percentage of a widget's total
+     * width or height, denoting a margin around the swipable area of the widget.
+     * Swipes must start and end inside this margin. This is important when the
+     * widget being swiped may not respond to the swipe if started at a point
+     * too near to the edge. The default is 10% from either edge.
+     *
+     * @return a value between 0 and 1
+     * @since API Level 16
+     */
+    public double getSwipeDeadZonePercentage() {
+        Tracer.trace();
+        return mSwipeDeadZonePercentage;
+    }
+
+    /**
+     * Sets the percentage of a widget's size that's considered as no-touch
+     * zone when swiping.
+     * The no-touch zone is set as percentage of a widget's total width or height,
+     * denoting a margin around the swipable area of the widget. Swipes must
+     * always start and end inside this margin. This is important when the
+     * widget being swiped may not respond to the swipe if started at a point
+     * too near to the edge. The default is 10% from either edge.
+     *
+     * @param swipeDeadZonePercentage is a value between 0 and 1
+     * @return reference to itself
+     * @since API Level 16
+     */
+    public UiScrollable setSwipeDeadZonePercentage(double swipeDeadZonePercentage) {
+        Tracer.trace(swipeDeadZonePercentage);
+        mSwipeDeadZonePercentage = swipeDeadZonePercentage;
+        return this;
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/UiSelector.java b/library/core-src/com/android/uiautomator/core/UiSelector.java
new file mode 100644
index 0000000..bd61bfd
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/UiSelector.java
@@ -0,0 +1,1022 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+import android.util.SparseArray;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import java.util.regex.Pattern;
+
+/**
+ * Specifies the elements in the layout hierarchy for tests to target, filtered
+ * by properties such as text value, content-description, class name, and state
+ * information. You can also target an element by its location in a layout
+ * hierarchy.
+ * @since API Level 16
+ */
+public class UiSelector {
+    static final int SELECTOR_NIL = 0;
+    static final int SELECTOR_TEXT = 1;
+    static final int SELECTOR_START_TEXT = 2;
+    static final int SELECTOR_CONTAINS_TEXT = 3;
+    static final int SELECTOR_CLASS = 4;
+    static final int SELECTOR_DESCRIPTION = 5;
+    static final int SELECTOR_START_DESCRIPTION = 6;
+    static final int SELECTOR_CONTAINS_DESCRIPTION = 7;
+    static final int SELECTOR_INDEX = 8;
+    static final int SELECTOR_INSTANCE = 9;
+    static final int SELECTOR_ENABLED = 10;
+    static final int SELECTOR_FOCUSED = 11;
+    static final int SELECTOR_FOCUSABLE = 12;
+    static final int SELECTOR_SCROLLABLE = 13;
+    static final int SELECTOR_CLICKABLE = 14;
+    static final int SELECTOR_CHECKED = 15;
+    static final int SELECTOR_SELECTED = 16;
+    static final int SELECTOR_ID = 17;
+    static final int SELECTOR_PACKAGE_NAME = 18;
+    static final int SELECTOR_CHILD = 19;
+    static final int SELECTOR_CONTAINER = 20;
+    static final int SELECTOR_PATTERN = 21;
+    static final int SELECTOR_PARENT = 22;
+    static final int SELECTOR_COUNT = 23;
+    static final int SELECTOR_LONG_CLICKABLE = 24;
+    static final int SELECTOR_TEXT_REGEX = 25;
+    static final int SELECTOR_CLASS_REGEX = 26;
+    static final int SELECTOR_DESCRIPTION_REGEX = 27;
+    static final int SELECTOR_PACKAGE_NAME_REGEX = 28;
+    static final int SELECTOR_RESOURCE_ID = 29;
+    static final int SELECTOR_CHECKABLE = 30;
+    static final int SELECTOR_RESOURCE_ID_REGEX = 31;
+
+    private SparseArray<Object> mSelectorAttributes = new SparseArray<Object>();
+
+    /**
+     * @since API Level 16
+     */
+    public UiSelector() {
+    }
+
+    UiSelector(UiSelector selector) {
+        mSelectorAttributes = selector.cloneSelector().mSelectorAttributes;
+    }
+
+    /**
+     * @since API Level 17
+     */
+    protected UiSelector cloneSelector() {
+        UiSelector ret = new UiSelector();
+        ret.mSelectorAttributes = mSelectorAttributes.clone();
+        if (hasChildSelector())
+            ret.mSelectorAttributes.put(SELECTOR_CHILD, new UiSelector(getChildSelector()));
+        if (hasParentSelector())
+            ret.mSelectorAttributes.put(SELECTOR_PARENT, new UiSelector(getParentSelector()));
+        if (hasPatternSelector())
+            ret.mSelectorAttributes.put(SELECTOR_PATTERN, new UiSelector(getPatternSelector()));
+        return ret;
+    }
+
+    static UiSelector patternBuilder(UiSelector selector) {
+        if (!selector.hasPatternSelector()) {
+            return new UiSelector().patternSelector(selector);
+        }
+        return selector;
+    }
+
+    static UiSelector patternBuilder(UiSelector container, UiSelector pattern) {
+        return new UiSelector(
+                new UiSelector().containerSelector(container).patternSelector(pattern));
+    }
+
+    /**
+     * Set the search criteria to match the visible text displayed
+     * in a widget (for example, the text label to launch an app).
+     *
+     * The text for the element must match exactly with the string in your input
+     * argument. Matching is case-sensitive.
+     *
+     * @param text Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector text(String text) {
+        return buildSelector(SELECTOR_TEXT, text);
+    }
+
+    /**
+     * Set the search criteria to match the visible text displayed in a layout
+     * element, using a regular expression.
+     *
+     * The text in the widget must match exactly with the string in your
+     * input argument.
+     *
+     * @param regex a regular expression
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public UiSelector textMatches(String regex) {
+        return buildSelector(SELECTOR_TEXT_REGEX, Pattern.compile(regex));
+    }
+
+    /**
+     * Set the search criteria to match visible text in a widget that is
+     * prefixed by the text parameter.
+     *
+     * The matching is case-insensitive.
+     *
+     * @param text Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector textStartsWith(String text) {
+        return buildSelector(SELECTOR_START_TEXT, text);
+    }
+
+    /**
+     * Set the search criteria to match the visible text in a widget
+     * where the visible text must contain the string in your input argument.
+     *
+     * The matching is case-sensitive.
+     *
+     * @param text Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector textContains(String text) {
+        return buildSelector(SELECTOR_CONTAINS_TEXT, text);
+    }
+
+    /**
+     * Set the search criteria to match the class property
+     * for a widget (for example, "android.widget.Button").
+     *
+     * @param className Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector className(String className) {
+        return buildSelector(SELECTOR_CLASS, className);
+    }
+
+    /**
+     * Set the search criteria to match the class property
+     * for a widget, using a regular expression.
+     *
+     * @param regex a regular expression
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public UiSelector classNameMatches(String regex) {
+        return buildSelector(SELECTOR_CLASS_REGEX, Pattern.compile(regex));
+    }
+
+    /**
+     * Set the search criteria to match the class property
+     * for a widget (for example, "android.widget.Button").
+     *
+     * @param type type
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public <T> UiSelector className(Class<T> type) {
+        return buildSelector(SELECTOR_CLASS, type.getName());
+    }
+
+    /**
+     * Set the search criteria to match the content-description
+     * property for a widget.
+     *
+     * The content-description is typically used
+     * by the Android Accessibility framework to
+     * provide an audio prompt for the widget when
+     * the widget is selected. The content-description
+     * for the widget must match exactly
+     * with the string in your input argument.
+     *
+     * Matching is case-sensitive.
+     *
+     * @param desc Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector description(String desc) {
+        return buildSelector(SELECTOR_DESCRIPTION, desc);
+    }
+
+    /**
+     * Set the search criteria to match the content-description
+     * property for a widget.
+     *
+     * The content-description is typically used
+     * by the Android Accessibility framework to
+     * provide an audio prompt for the widget when
+     * the widget is selected. The content-description
+     * for the widget must match exactly
+     * with the string in your input argument.
+     *
+     * @param regex a regular expression
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public UiSelector descriptionMatches(String regex) {
+        return buildSelector(SELECTOR_DESCRIPTION_REGEX, Pattern.compile(regex));
+    }
+
+    /**
+     * Set the search criteria to match the content-description
+     * property for a widget.
+     *
+     * The content-description is typically used
+     * by the Android Accessibility framework to
+     * provide an audio prompt for the widget when
+     * the widget is selected. The content-description
+     * for the widget must start
+     * with the string in your input argument.
+     *
+     * Matching is case-insensitive.
+     *
+     * @param desc Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector descriptionStartsWith(String desc) {
+        return buildSelector(SELECTOR_START_DESCRIPTION, desc);
+    }
+
+    /**
+     * Set the search criteria to match the content-description
+     * property for a widget.
+     *
+     * The content-description is typically used
+     * by the Android Accessibility framework to
+     * provide an audio prompt for the widget when
+     * the widget is selected. The content-description
+     * for the widget must contain
+     * the string in your input argument.
+     *
+     * Matching is case-insensitive.
+     *
+     * @param desc Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector descriptionContains(String desc) {
+        return buildSelector(SELECTOR_CONTAINS_DESCRIPTION, desc);
+    }
+
+    /**
+     * Set the search criteria to match the given resource ID.
+     *
+     * @param id Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 18
+     */
+    public UiSelector resourceId(String id) {
+        return buildSelector(SELECTOR_RESOURCE_ID, id);
+    }
+
+    /**
+     * Set the search criteria to match the resource ID
+     * of the widget, using a regular expression.http://blog.bettersoftwaretesting.com/
+     *
+     * @param regex a regular expression
+     * @return UiSelector with the specified search criteria
+     * @since API Level 18
+     */
+    public UiSelector resourceIdMatches(String regex) {
+        return buildSelector(SELECTOR_RESOURCE_ID_REGEX, Pattern.compile(regex));
+    }
+
+    /**
+     * Set the search criteria to match the widget by its node
+     * index in the layout hierarchy.
+     *
+     * The index value must be 0 or greater.
+     *
+     * Using the index can be unreliable and should only
+     * be used as a last resort for matching. Instead,
+     * consider using the {@link #instance(int)} method.
+     *
+     * @param index Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector index(final int index) {
+        return buildSelector(SELECTOR_INDEX, index);
+    }
+
+    /**
+     * Set the search criteria to match the
+     * widget by its instance number.
+     *
+     * The instance value must be 0 or greater, where
+     * the first instance is 0.
+     *
+     * For example, to simulate a user click on
+     * the third image that is enabled in a UI screen, you
+     * could specify a a search criteria where the instance is
+     * 2, the {@link #className(String)} matches the image
+     * widget class, and {@link #enabled(boolean)} is true.
+     * The code would look like this:
+     * <code>
+     * new UiSelector().className("android.widget.ImageView")
+     *    .enabled(true).instance(2);
+     * </code>
+     *
+     * @param instance Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector instance(final int instance) {
+        return buildSelector(SELECTOR_INSTANCE, instance);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are enabled.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector enabled(boolean val) {
+        return buildSelector(SELECTOR_ENABLED, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that have focus.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector focused(boolean val) {
+        return buildSelector(SELECTOR_FOCUSED, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are focusable.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector focusable(boolean val) {
+        return buildSelector(SELECTOR_FOCUSABLE, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are scrollable.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector scrollable(boolean val) {
+        return buildSelector(SELECTOR_SCROLLABLE, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that
+     * are currently selected.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector selected(boolean val) {
+        return buildSelector(SELECTOR_SELECTED, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that
+     * are currently checked (usually for checkboxes).
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector checked(boolean val) {
+        return buildSelector(SELECTOR_CHECKED, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are clickable.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector clickable(boolean val) {
+        return buildSelector(SELECTOR_CLICKABLE, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are checkable.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 18
+     */
+    public UiSelector checkable(boolean val) {
+        return buildSelector(SELECTOR_CHECKABLE, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are long-clickable.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public UiSelector longClickable(boolean val) {
+        return buildSelector(SELECTOR_LONG_CLICKABLE, val);
+    }
+
+    /**
+     * Adds a child UiSelector criteria to this selector.
+     *
+     * Use this selector to narrow the search scope to
+     * child widgets under a specific parent widget.
+     *
+     * @param selector
+     * @return UiSelector with this added search criterion
+     * @since API Level 16
+     */
+    public UiSelector childSelector(UiSelector selector) {
+        return buildSelector(SELECTOR_CHILD, selector);
+    }
+
+    private UiSelector patternSelector(UiSelector selector) {
+        return buildSelector(SELECTOR_PATTERN, selector);
+    }
+
+    private UiSelector containerSelector(UiSelector selector) {
+        return buildSelector(SELECTOR_CONTAINER, selector);
+    }
+
+    /**
+     * Adds a child UiSelector criteria to this selector which is used to
+     * start search from the parent widget.
+     *
+     * Use this selector to narrow the search scope to
+     * sibling widgets as well all child widgets under a parent.
+     *
+     * @param selector
+     * @return UiSelector with this added search criterion
+     * @since API Level 16
+     */
+    public UiSelector fromParent(UiSelector selector) {
+        return buildSelector(SELECTOR_PARENT, selector);
+    }
+
+    /**
+     * Set the search criteria to match the package name
+     * of the application that contains the widget.
+     *
+     * @param name Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector packageName(String name) {
+        return buildSelector(SELECTOR_PACKAGE_NAME, name);
+    }
+
+    /**
+     * Set the search criteria to match the package name
+     * of the application that contains the widget.
+     *
+     * @param regex a regular expression
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public UiSelector packageNameMatches(String regex) {
+        return buildSelector(SELECTOR_PACKAGE_NAME_REGEX, Pattern.compile(regex));
+    }
+
+    /**
+     * Building a UiSelector always returns a new UiSelector and never modifies the
+     * existing UiSelector being used.
+     */
+    private UiSelector buildSelector(int selectorId, Object selectorValue) {
+        UiSelector selector = new UiSelector(this);
+        if (selectorId == SELECTOR_CHILD || selectorId == SELECTOR_PARENT)
+            selector.getLastSubSelector().mSelectorAttributes.put(selectorId, selectorValue);
+        else
+            selector.mSelectorAttributes.put(selectorId, selectorValue);
+        return selector;
+    }
+
+    /**
+     * Selectors may have a hierarchy defined by specifying child nodes to be matched.
+     * It is not necessary that every selector have more than one level. A selector
+     * can also be a single level referencing only one node. In such cases the return
+     * it null.
+     *
+     * @return a child selector if one exists. Else null if this selector does not
+     * reference child node.
+     */
+    UiSelector getChildSelector() {
+        UiSelector selector = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD, null);
+        if (selector != null)
+            return new UiSelector(selector);
+        return null;
+    }
+
+    UiSelector getPatternSelector() {
+        UiSelector selector =
+                (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PATTERN, null);
+        if (selector != null)
+            return new UiSelector(selector);
+        return null;
+    }
+
+    UiSelector getContainerSelector() {
+        UiSelector selector =
+                (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CONTAINER, null);
+        if (selector != null)
+            return new UiSelector(selector);
+        return null;
+    }
+
+    UiSelector getParentSelector() {
+        UiSelector selector =
+                (UiSelector) mSelectorAttributes.get(UiSelector.SELECTOR_PARENT, null);
+        if (selector != null)
+            return new UiSelector(selector);
+        return null;
+    }
+
+    int getInstance() {
+        return getInt(UiSelector.SELECTOR_INSTANCE);
+    }
+
+    String getString(int criterion) {
+        return (String) mSelectorAttributes.get(criterion, null);
+    }
+
+    boolean getBoolean(int criterion) {
+        return (Boolean) mSelectorAttributes.get(criterion, false);
+    }
+
+    int getInt(int criterion) {
+        return (Integer) mSelectorAttributes.get(criterion, 0);
+    }
+
+    Pattern getPattern(int criterion) {
+        return (Pattern) mSelectorAttributes.get(criterion, null);
+    }
+
+    boolean isMatchFor(AccessibilityNodeInfo node, int index) {
+        int size = mSelectorAttributes.size();
+        for(int x = 0; x < size; x++) {
+            CharSequence s = null;
+            int criterion = mSelectorAttributes.keyAt(x);
+            switch(criterion) {
+            case UiSelector.SELECTOR_INDEX:
+                if (index != this.getInt(criterion))
+                    return false;
+                break;
+            case UiSelector.SELECTOR_CHECKED:
+                if (node.isChecked() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CLASS:
+                s = node.getClassName();
+                if (s == null || !s.toString().contentEquals(getString(criterion))) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CLASS_REGEX:
+                s = node.getClassName();
+                if (s == null || !getPattern(criterion).matcher(s).matches()) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CLICKABLE:
+                if (node.isClickable() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CHECKABLE:
+                if (node.isCheckable() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_LONG_CLICKABLE:
+                if (node.isLongClickable() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CONTAINS_DESCRIPTION:
+                s = node.getContentDescription();
+                if (s == null || !s.toString().toLowerCase()
+                        .contains(getString(criterion).toLowerCase())) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_START_DESCRIPTION:
+                s = node.getContentDescription();
+                if (s == null || !s.toString().toLowerCase()
+                        .startsWith(getString(criterion).toLowerCase())) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_DESCRIPTION:
+                s = node.getContentDescription();
+                if (s == null || !s.toString().contentEquals(getString(criterion))) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_DESCRIPTION_REGEX:
+                s = node.getContentDescription();
+                if (s == null || !getPattern(criterion).matcher(s).matches()) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CONTAINS_TEXT:
+                s = node.getText();
+                if (s == null || !s.toString().toLowerCase()
+                        .contains(getString(criterion).toLowerCase())) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_START_TEXT:
+                s = node.getText();
+                if (s == null || !s.toString().toLowerCase()
+                        .startsWith(getString(criterion).toLowerCase())) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_TEXT:
+                s = node.getText();
+                if (s == null || !s.toString().contentEquals(getString(criterion))) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_TEXT_REGEX:
+                s = node.getText();
+                if (s == null || !getPattern(criterion).matcher(s).matches()) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_ENABLED:
+                if (node.isEnabled() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_FOCUSABLE:
+                if (node.isFocusable() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_FOCUSED:
+                if (node.isFocused() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_ID:
+                break; //TODO: do we need this for AccessibilityNodeInfo.id?
+            case UiSelector.SELECTOR_PACKAGE_NAME:
+                s = node.getPackageName();
+                if (s == null || !s.toString().contentEquals(getString(criterion))) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_PACKAGE_NAME_REGEX:
+                s = node.getPackageName();
+                if (s == null || !getPattern(criterion).matcher(s).matches()) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_SCROLLABLE:
+                if (node.isScrollable() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_SELECTED:
+                if (node.isSelected() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_RESOURCE_ID:
+                s = node.getViewIdResourceName();
+                if (s == null || !s.toString().contentEquals(getString(criterion))) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_RESOURCE_ID_REGEX:
+                s = node.getViewIdResourceName();
+                if (s == null || !getPattern(criterion).matcher(s).matches()) {
+                    return false;
+                }
+                break;
+            }
+        }
+        return matchOrUpdateInstance();
+    }
+
+    private boolean matchOrUpdateInstance() {
+        int currentSelectorCounter = 0;
+        int currentSelectorInstance = 0;
+
+        // matched attributes - now check for matching instance number
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_INSTANCE) >= 0) {
+            currentSelectorInstance =
+                    (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_INSTANCE);
+        }
+
+        // instance is required. Add count if not already counting
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_COUNT) >= 0) {
+            currentSelectorCounter = (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_COUNT);
+        }
+
+        // Verify
+        if (currentSelectorInstance == currentSelectorCounter) {
+            return true;
+        }
+        // Update count
+        if (currentSelectorInstance > currentSelectorCounter) {
+            mSelectorAttributes.put(UiSelector.SELECTOR_COUNT, ++currentSelectorCounter);
+        }
+        return false;
+    }
+
+    /**
+     * Leaf selector indicates no more child or parent selectors
+     * are declared in the this selector.
+     * @return true if is leaf.
+     */
+    boolean isLeaf() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0 &&
+                mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) {
+            return true;
+        }
+        return false;
+    }
+
+    boolean hasChildSelector() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0) {
+            return false;
+        }
+        return true;
+    }
+
+    boolean hasPatternSelector() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PATTERN) < 0) {
+            return false;
+        }
+        return true;
+    }
+
+    boolean hasContainerSelector() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CONTAINER) < 0) {
+            return false;
+        }
+        return true;
+    }
+
+    boolean hasParentSelector() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns the deepest selector in the chain of possible sub selectors.
+     * A chain of selector is created when either of {@link UiSelector#childSelector(UiSelector)}
+     * or {@link UiSelector#fromParent(UiSelector)} are used once or more in the construction of
+     * a selector.
+     * @return last UiSelector in chain
+     */
+    private UiSelector getLastSubSelector() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) >= 0) {
+            UiSelector child = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD);
+            if (child.getLastSubSelector() == null) {
+                return child;
+            }
+            return child.getLastSubSelector();
+        } else if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) >= 0) {
+            UiSelector parent = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PARENT);
+            if (parent.getLastSubSelector() == null) {
+                return parent;
+            }
+            return parent.getLastSubSelector();
+        }
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return dumpToString(true);
+    }
+
+    String dumpToString(boolean all) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(UiSelector.class.getSimpleName() + "[");
+        final int criterionCount = mSelectorAttributes.size();
+        for (int i = 0; i < criterionCount; i++) {
+            if (i > 0) {
+                builder.append(", ");
+            }
+            final int criterion = mSelectorAttributes.keyAt(i);
+            switch (criterion) {
+            case SELECTOR_TEXT:
+                builder.append("TEXT=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_TEXT_REGEX:
+                builder.append("TEXT_REGEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_START_TEXT:
+                builder.append("START_TEXT=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CONTAINS_TEXT:
+                builder.append("CONTAINS_TEXT=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CLASS:
+                builder.append("CLASS=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CLASS_REGEX:
+                builder.append("CLASS_REGEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_DESCRIPTION:
+                builder.append("DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_DESCRIPTION_REGEX:
+                builder.append("DESCRIPTION_REGEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_START_DESCRIPTION:
+                builder.append("START_DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CONTAINS_DESCRIPTION:
+                builder.append("CONTAINS_DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_INDEX:
+                builder.append("INDEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_INSTANCE:
+                builder.append("INSTANCE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_ENABLED:
+                builder.append("ENABLED=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_FOCUSED:
+                builder.append("FOCUSED=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_FOCUSABLE:
+                builder.append("FOCUSABLE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_SCROLLABLE:
+                builder.append("SCROLLABLE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CLICKABLE:
+                builder.append("CLICKABLE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CHECKABLE:
+                builder.append("CHECKABLE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_LONG_CLICKABLE:
+                builder.append("LONG_CLICKABLE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CHECKED:
+                builder.append("CHECKED=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_SELECTED:
+                builder.append("SELECTED=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_ID:
+                builder.append("ID=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CHILD:
+                if (all)
+                    builder.append("CHILD=").append(mSelectorAttributes.valueAt(i));
+                else
+                    builder.append("CHILD[..]");
+                break;
+            case SELECTOR_PATTERN:
+                if (all)
+                    builder.append("PATTERN=").append(mSelectorAttributes.valueAt(i));
+                else
+                    builder.append("PATTERN[..]");
+                break;
+            case SELECTOR_CONTAINER:
+                if (all)
+                    builder.append("CONTAINER=").append(mSelectorAttributes.valueAt(i));
+                else
+                    builder.append("CONTAINER[..]");
+                break;
+            case SELECTOR_PARENT:
+                if (all)
+                    builder.append("PARENT=").append(mSelectorAttributes.valueAt(i));
+                else
+                    builder.append("PARENT[..]");
+                break;
+            case SELECTOR_COUNT:
+                builder.append("COUNT=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_PACKAGE_NAME:
+                builder.append("PACKAGE NAME=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_PACKAGE_NAME_REGEX:
+                builder.append("PACKAGE_NAME_REGEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_RESOURCE_ID:
+                builder.append("RESOURCE_ID=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_RESOURCE_ID_REGEX:
+                builder.append("RESOURCE_ID_REGEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            default:
+                builder.append("UNDEFINED="+criterion+" ").append(mSelectorAttributes.valueAt(i));
+            }
+        }
+        builder.append("]");
+        return builder.toString();
+    }
+}
diff --git a/library/core-src/com/android/uiautomator/core/UiWatcher.java b/library/core-src/com/android/uiautomator/core/UiWatcher.java
new file mode 100644
index 0000000..5403e30
--- /dev/null
+++ b/library/core-src/com/android/uiautomator/core/UiWatcher.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+/**
+ * See {@link UiDevice#registerWatcher(String, UiWatcher)} on how to register a
+ * a condition watcher to be called by the automation library. The automation library will
+ * invoke checkForCondition() only when a regular API call is in retry mode because it is unable
+ * to locate its selector yet. Only during this time, the watchers are invoked to check if there is
+ * something else unexpected on the screen.
+ * @since API Level 16
+ */
+public interface UiWatcher {
+
+    /**
+     * Custom handler that is automatically called when the testing framework is unable to
+     * find a match using the {@link UiSelector}
+     *
+     * When the framework is in the process of matching a {@link UiSelector} and it
+     * is unable to match any widget based on the specified criteria in the selector,
+     * the framework will perform retries for a predetermined time, waiting for the display
+     * to update and show the desired widget. While the framework is in this state, it will call
+     * registered watchers' checkForCondition(). This gives the registered watchers a chance
+     * to take a look at the display and see if there is a recognized condition that can be
+     * handled and in doing so allowing the current test to continue.
+     *
+     * An example usage would be to look for dialogs popped due to other background
+     * processes requesting user attention and have nothing to do with the application
+     * currently under test.
+     *
+     * @return true to indicate a matched condition or false for nothing was matched
+     * @since API Level 16
+     */
+    public boolean checkForCondition();
+}
diff --git a/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
new file mode 100644
index 0000000..1afa513
--- /dev/null
+++ b/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.core;
+
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.app.IActivityManager.ContentProviderHolder;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.content.IContentProvider;
+import android.database.Cursor;
+import android.hardware.display.DisplayManagerGlobal;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IPowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Display;
+import android.view.IWindowManager;
+
+/**
+ * @hide
+ */
+public class ShellUiAutomatorBridge extends UiAutomatorBridge {
+
+    private static final String LOG_TAG = ShellUiAutomatorBridge.class.getSimpleName();
+
+    public ShellUiAutomatorBridge(UiAutomation uiAutomation) {
+        super(uiAutomation);
+    }
+
+    public Display getDefaultDisplay() {
+        return DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
+    }
+
+    public long getSystemLongPressTime() {
+        // Read the long press timeout setting.
+        long longPressTimeout = 0;
+        try {
+            IContentProvider provider = null;
+            Cursor cursor = null;
+            IActivityManager activityManager = ActivityManagerNative.getDefault();
+            String providerName = Settings.Secure.CONTENT_URI.getAuthority();
+            IBinder token = new Binder();
+            try {
+                ContentProviderHolder holder = activityManager.getContentProviderExternal(
+                        providerName, UserHandle.USER_OWNER, token);
+                if (holder == null) {
+                    throw new IllegalStateException("Could not find provider: " + providerName);
+                }
+                provider = holder.provider;
+                cursor = provider.query(null, Settings.Secure.CONTENT_URI,
+                        new String[] {
+                            Settings.Secure.VALUE
+                        }, "name=?",
+                        new String[] {
+                            Settings.Secure.LONG_PRESS_TIMEOUT
+                        }, null, null);
+                if (cursor.moveToFirst()) {
+                    longPressTimeout = cursor.getInt(0);
+                }
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+                if (provider != null) {
+                    activityManager.removeContentProviderExternal(providerName, token);
+                }
+            }
+        } catch (RemoteException e) {
+            String message = "Error reading long press timeout setting.";
+            Log.e(LOG_TAG, message, e);
+            throw new RuntimeException(message, e);
+        }
+        return longPressTimeout;
+    }
+
+    @Override
+    public int getRotation() {
+        IWindowManager wm =
+                IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
+        int ret = -1;
+        try {
+            ret = wm.getRotation();
+        } catch (RemoteException e) {
+            Log.e(LOG_TAG, "Error getting screen rotation", e);
+            throw new RuntimeException(e);
+        }
+        return ret;
+    }
+
+    @Override
+    public boolean isScreenOn() {
+        IPowerManager pm =
+                IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));
+        boolean ret = false;
+        try {
+            ret = pm.isScreenOn();
+        } catch (RemoteException e) {
+            Log.e(LOG_TAG, "Error getting screen status", e);
+            throw new RuntimeException(e);
+        }
+        return ret;
+    }
+}
diff --git a/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java b/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
new file mode 100644
index 0000000..1fa9bac
--- /dev/null
+++ b/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
@@ -0,0 +1,127 @@
+package com.android.uiautomator.core;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
+import android.app.IActivityController;
+import android.app.IActivityManager;
+import android.app.UiAutomation;
+import android.app.UiAutomationConnection;
+import android.content.Intent;
+import android.os.HandlerThread;
+import android.os.RemoteException;
+
+/**
+ * @hide
+ */
+public class UiAutomationShellWrapper {
+
+    private static final String HANDLER_THREAD_NAME = "UiAutomatorHandlerThread";
+
+    private final HandlerThread mHandlerThread = new HandlerThread(HANDLER_THREAD_NAME);
+
+    private UiAutomation mUiAutomation;
+
+    public void connect() {
+        if (mHandlerThread.isAlive()) {
+            throw new IllegalStateException("Already connected!");
+        }
+        mHandlerThread.start();
+        mUiAutomation = new UiAutomation(mHandlerThread.getLooper(),
+                new UiAutomationConnection());
+        mUiAutomation.connect();
+    }
+
+    /**
+     * Enable or disable monkey test mode.
+     *
+     * Setting test as "monkey" indicates to some applications that a test framework is
+     * running as a "monkey" type. Such applications may choose not to perform actions that
+     * do submits so to avoid allowing monkey tests from doing harm or performing annoying
+     * actions such as dialing 911 or posting messages to public forums, etc.
+     *
+     * @param isSet True to set as monkey test. False to set as regular functional test (default).
+     * @see {@link ActivityManager#isUserAMonkey()}
+     */
+    public void setRunAsMonkey(boolean isSet) {
+        IActivityManager am = ActivityManagerNative.getDefault();
+        if (am == null) {
+            throw new RuntimeException("Can't manage monkey status; is the system running?");
+        }
+        try {
+            if (isSet) {
+                am.setActivityController(new DummyActivityController());
+            } else {
+                am.setActivityController(null);
+            }
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void disconnect() {
+        if (!mHandlerThread.isAlive()) {
+            throw new IllegalStateException("Already disconnected!");
+        }
+        mUiAutomation.disconnect();
+        mHandlerThread.quit();
+    }
+
+    public UiAutomation getUiAutomation() {
+        return mUiAutomation;
+    }
+
+    public void setCompressedLayoutHierarchy(boolean compressed) {
+        AccessibilityServiceInfo info = mUiAutomation.getServiceInfo();
+        if (compressed)
+            info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+        else
+            info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+        mUiAutomation.setServiceInfo(info);
+    }
+
+    /**
+     * Dummy, no interference, activity controller.
+     */
+    private class DummyActivityController extends IActivityController.Stub {
+        @Override
+        public boolean activityStarting(Intent intent, String pkg) throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return true;
+        }
+
+        @Override
+        public boolean activityResuming(String pkg) throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return true;
+        }
+
+        @Override
+        public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
+                long timeMillis, String stackTrace) throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return true;
+        }
+
+        @Override
+        public int appEarlyNotResponding(String processName, int pid, String annotation)
+                throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return 0;
+        }
+
+        @Override
+        public int appNotResponding(String processName, int pid, String processStats)
+                throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return 0;
+        }
+
+        @Override
+        public int systemNotResponding(String message)
+                throws RemoteException {
+            /* do nothing and let system proceed normally */
+            return 0;
+        }
+    }
+}
diff --git a/library/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java b/library/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java
new file mode 100644
index 0000000..f0c60d2
--- /dev/null
+++ b/library/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.testrunner;
+
+import android.os.Bundle;
+
+/**
+ * Provides auxiliary support for running test cases
+ *
+ * @since API Level 16
+ */
+public interface IAutomationSupport {
+
+    /**
+     * Allows the running test cases to send out interim status
+     *
+     * @param resultCode
+     * @param status status report, consisting of key value pairs
+     * @since API Level 16
+     */
+    public void sendStatus(int resultCode, Bundle status);
+
+}
diff --git a/library/testrunner-src/com/android/uiautomator/testrunner/TestCaseCollector.java b/library/testrunner-src/com/android/uiautomator/testrunner/TestCaseCollector.java
new file mode 100644
index 0000000..cda49f6
--- /dev/null
+++ b/library/testrunner-src/com/android/uiautomator/testrunner/TestCaseCollector.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.testrunner;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A convenient class that encapsulates functions for adding test classes
+ *
+ * @hide
+ */
+public class TestCaseCollector {
+
+    private ClassLoader mClassLoader;
+    private List<TestCase> mTestCases;
+    private TestCaseFilter mFilter;
+
+    public TestCaseCollector(ClassLoader classLoader, TestCaseFilter filter) {
+        mClassLoader = classLoader;
+        mTestCases = new ArrayList<TestCase>();
+        mFilter = filter;
+    }
+
+    /**
+     * Adds classes to test by providing a list of class names in string
+     *
+     * The class name may be in "<class name>#<method name>" format
+     *
+     * @param classNames class must be subclass of {@link UiAutomatorTestCase}
+     * @throws ClassNotFoundException
+     */
+    public void addTestClasses(List<String> classNames) throws ClassNotFoundException {
+        for (String className : classNames) {
+            addTestClass(className);
+        }
+    }
+
+    /**
+     * Adds class to test by providing class name in string.
+     *
+     * The class name may be in "<class name>#<method name>" format
+     *
+     * @param className classes must be subclass of {@link UiAutomatorTestCase}
+     * @throws ClassNotFoundException
+     */
+    public void addTestClass(String className) throws ClassNotFoundException {
+        int hashPos = className.indexOf('#');
+        String methodName = null;
+        if (hashPos != -1) {
+            methodName = className.substring(hashPos + 1);
+            className = className.substring(0, hashPos);
+        }
+        addTestClass(className, methodName);
+    }
+
+    /**
+     * Adds class to test by providing class name and method name in separate strings
+     *
+     * @param className class must be subclass of {@link UiAutomatorTestCase}
+     * @param methodName may be null, in which case all "public void testNNN(void)" functions
+     *                   will be added
+     * @throws ClassNotFoundException
+     */
+    public void addTestClass(String className, String methodName) throws ClassNotFoundException {
+        Class<?> clazz = mClassLoader.loadClass(className);
+        if (methodName != null) {
+            addSingleTestMethod(clazz, methodName);
+        } else {
+            Method[] methods = clazz.getMethods();
+            for (Method method : methods) {
+                if (mFilter.accept(method)) {
+                    addSingleTestMethod(clazz, method.getName());
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the list of added test cases so far
+     * @return a list of {@link TestCase}
+     */
+    public List<TestCase> getTestCases() {
+        return Collections.unmodifiableList(mTestCases);
+    }
+
+    protected void addSingleTestMethod(Class<?> clazz, String method) {
+        if (!(mFilter.accept(clazz))) {
+            throw new RuntimeException("Test class must be derived from UiAutomatorTestCase");
+        }
+        try {
+            TestCase testCase = (TestCase) clazz.newInstance();
+            testCase.setName(method);
+            mTestCases.add(testCase);
+        } catch (InstantiationException e) {
+            mTestCases.add(error(clazz, "InstantiationException: could not instantiate " +
+                    "test class. Class: " + clazz.getName()));
+        } catch (IllegalAccessException e) {
+            mTestCases.add(error(clazz, "IllegalAccessException: could not instantiate " +
+                    "test class. Class: " + clazz.getName()));
+        }
+    }
+
+    private UiAutomatorTestCase error(Class<?> clazz, final String message) {
+        UiAutomatorTestCase warning = new UiAutomatorTestCase() {
+            protected void runTest() {
+                fail(message);
+            }
+        };
+
+        warning.setName(clazz.getName());
+        return warning;
+    }
+
+    /**
+     * Determine if a class and its method should be accepted into test suite
+     *
+     */
+    public interface TestCaseFilter {
+
+        /**
+         * Determine that based on the method signature, if it can be accepted
+         * @param method
+         */
+        public boolean accept(Method method);
+
+        /**
+         * Determine that based on the class type, if it can be accepted
+         * @param clazz
+         * @return
+         */
+        public boolean accept(Class<?> clazz);
+    }
+}
diff --git a/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java b/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
new file mode 100644
index 0000000..e7d961b
--- /dev/null
+++ b/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.testrunner;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.view.inputmethod.InputMethodInfo;
+
+import com.android.internal.view.IInputMethodManager;
+import com.android.uiautomator.core.UiDevice;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+
+/**
+ * UI automation test should extend this class. This class provides access
+ * to the following:
+ * {@link UiDevice} instance
+ * {@link Bundle} for command line parameters.
+ * @since API Level 16
+ */
+public class UiAutomatorTestCase extends TestCase {
+
+    private static final String DISABLE_IME = "disable_ime";
+    private static final String DUMMY_IME_PACKAGE = "com.android.testing.dummyime";
+    private UiDevice mUiDevice;
+    private Bundle mParams;
+    private IAutomationSupport mAutomationSupport;
+    private boolean mShouldDisableIme = false;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mShouldDisableIme = "true".equals(mParams.getString(DISABLE_IME));
+        if (mShouldDisableIme) {
+            setDummyIme();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mShouldDisableIme) {
+            restoreActiveIme();
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Get current instance of {@link UiDevice}. Works similar to calling the static
+     * {@link UiDevice#getInstance()} from anywhere in the test classes.
+     * @since API Level 16
+     */
+    public UiDevice getUiDevice() {
+        return mUiDevice;
+    }
+
+    /**
+     * Get command line parameters. On the command line when passing <code>-e key value</code>
+     * pairs, the {@link Bundle} will have the key value pairs conveniently available to the
+     * tests.
+     * @since API Level 16
+     */
+    public Bundle getParams() {
+        return mParams;
+    }
+
+    /**
+     * Provides support for running tests to report interim status
+     *
+     * @return IAutomationSupport
+     * @since API Level 16
+     */
+    public IAutomationSupport getAutomationSupport() {
+        return mAutomationSupport;
+    }
+
+    /**
+     * package private
+     * @param uiDevice
+     */
+    void setUiDevice(UiDevice uiDevice) {
+        mUiDevice = uiDevice;
+    }
+
+    /**
+     * package private
+     * @param params
+     */
+    void setParams(Bundle params) {
+        mParams = params;
+    }
+
+    void setAutomationSupport(IAutomationSupport automationSupport) {
+        mAutomationSupport = automationSupport;
+    }
+
+    /**
+     * Calls {@link SystemClock#sleep(long)} to sleep
+     * @param ms is in milliseconds.
+     * @since API Level 16
+     */
+    public void sleep(long ms) {
+        SystemClock.sleep(ms);
+    }
+
+    private void setDummyIme() throws RemoteException {
+        IInputMethodManager im = IInputMethodManager.Stub.asInterface(ServiceManager
+                .getService(Context.INPUT_METHOD_SERVICE));
+        List<InputMethodInfo> infos = im.getInputMethodList();
+        String id = null;
+        for (InputMethodInfo info : infos) {
+            if (DUMMY_IME_PACKAGE.equals(info.getComponent().getPackageName())) {
+                id = info.getId();
+            }
+        }
+        if (id == null) {
+            throw new RuntimeException(String.format(
+                    "Required testing fixture missing: IME package (%s)", DUMMY_IME_PACKAGE));
+        }
+        im.setInputMethod(null, id);
+    }
+
+    private void restoreActiveIme() throws RemoteException {
+        // TODO: figure out a way to restore active IME
+        // Currently retrieving active IME requires querying secure settings provider, which is hard
+        // to do without a Context; so the caveat here is that to make the post test device usable,
+        // the active IME needs to be manually switched.
+    }
+}
diff --git a/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCaseFilter.java b/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCaseFilter.java
new file mode 100644
index 0000000..1de5a4d
--- /dev/null
+++ b/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCaseFilter.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.testrunner;
+
+import com.android.uiautomator.testrunner.TestCaseCollector.TestCaseFilter;
+
+import java.lang.reflect.Method;
+
+/**
+ * A {@link TestCaseFilter} that accepts testFoo methods and {@link UiAutomatorTestCase} classes
+ *
+ * @hide
+ */
+public class UiAutomatorTestCaseFilter implements TestCaseFilter {
+
+    @Override
+    public boolean accept(Method method) {
+        return ((method.getParameterTypes().length == 0) &&
+                (method.getName().startsWith("test")) &&
+                (method.getReturnType().getSimpleName().equals("void")));
+    }
+
+    @Override
+    public boolean accept(Class<?> clazz) {
+        return UiAutomatorTestCase.class.isAssignableFrom(clazz);
+    }
+
+}
diff --git a/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java b/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java
new file mode 100644
index 0000000..ef167f9
--- /dev/null
+++ b/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.testrunner;
+
+import android.app.Activity;
+import android.app.IInstrumentationWatcher;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.SystemClock;
+import android.test.RepetitiveTest;
+import android.util.Log;
+
+import com.android.uiautomator.core.ShellUiAutomatorBridge;
+import com.android.uiautomator.core.Tracer;
+import com.android.uiautomator.core.UiAutomationShellWrapper;
+import com.android.uiautomator.core.UiDevice;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import junit.runner.BaseTestRunner;
+import junit.textui.ResultPrinter;
+
+/**
+ * @hide
+ */
+public class UiAutomatorTestRunner {
+
+    private static final String LOGTAG = UiAutomatorTestRunner.class.getSimpleName();
+    private static final int EXIT_OK = 0;
+    private static final int EXIT_EXCEPTION = -1;
+
+    private static final String HANDLER_THREAD_NAME = "UiAutomatorHandlerThread";
+
+    private boolean mDebug;
+    private boolean mMonkey;
+    private Bundle mParams = null;
+    private UiDevice mUiDevice;
+    private List<String> mTestClasses = null;
+    private final FakeInstrumentationWatcher mWatcher = new FakeInstrumentationWatcher();
+    private final IAutomationSupport mAutomationSupport = new IAutomationSupport() {
+        @Override
+        public void sendStatus(int resultCode, Bundle status) {
+            mWatcher.instrumentationStatus(null, resultCode, status);
+        }
+    };
+    private final List<TestListener> mTestListeners = new ArrayList<TestListener>();
+
+    private HandlerThread mHandlerThread;
+
+    public void run(List<String> testClasses, Bundle params, boolean debug, boolean monkey) {
+        Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
+            @Override
+            public void uncaughtException(Thread thread, Throwable ex) {
+                Log.e(LOGTAG, "uncaught exception", ex);
+                Bundle results = new Bundle();
+                results.putString("shortMsg", ex.getClass().getName());
+                results.putString("longMsg", ex.getMessage());
+                mWatcher.instrumentationFinished(null, 0, results);
+                // bailing on uncaught exception
+                System.exit(EXIT_EXCEPTION);
+            }
+        });
+
+        mTestClasses = testClasses;
+        mParams = params;
+        mDebug = debug;
+        mMonkey = monkey;
+        start();
+        System.exit(EXIT_OK);
+    }
+
+    /**
+     * Called after all test classes are in place, ready to test
+     */
+    protected void start() {
+        TestCaseCollector collector = getTestCaseCollector(this.getClass().getClassLoader());
+        try {
+            collector.addTestClasses(mTestClasses);
+        } catch (ClassNotFoundException e) {
+            // will be caught by uncaught handler
+            throw new RuntimeException(e.getMessage(), e);
+        }
+        if (mDebug) {
+            Debug.waitForDebugger();
+        }
+        mHandlerThread = new HandlerThread(HANDLER_THREAD_NAME);
+        mHandlerThread.setDaemon(true);
+        mHandlerThread.start();
+        UiAutomationShellWrapper automationWrapper = new UiAutomationShellWrapper();
+        automationWrapper.connect();
+
+        long startTime = SystemClock.uptimeMillis();
+        TestResult testRunResult = new TestResult();
+        ResultReporter resultPrinter;
+        String outputFormat = mParams.getString("outputFormat");
+        List<TestCase> testCases = collector.getTestCases();
+        Bundle testRunOutput = new Bundle();
+        if ("simple".equals(outputFormat)) {
+            resultPrinter = new SimpleResultPrinter(System.out, true);
+        } else {
+            resultPrinter = new WatcherResultPrinter(testCases.size());
+        }
+        try {
+            automationWrapper.setRunAsMonkey(mMonkey);
+            mUiDevice = UiDevice.getInstance();
+            mUiDevice.initialize(new ShellUiAutomatorBridge(automationWrapper.getUiAutomation()));
+
+            String traceType = mParams.getString("traceOutputMode");
+            if(traceType != null) {
+                Tracer.Mode mode = Tracer.Mode.valueOf(Tracer.Mode.class, traceType);
+                if (mode == Tracer.Mode.FILE || mode == Tracer.Mode.ALL) {
+                    String filename = mParams.getString("traceLogFilename");
+                    if (filename == null) {
+                        throw new RuntimeException("Name of log file not specified. " +
+                                "Please specify it using traceLogFilename parameter");
+                    }
+                    Tracer.getInstance().setOutputFilename(filename);
+                }
+                Tracer.getInstance().setOutputMode(mode);
+            }
+
+            // add test listeners
+            testRunResult.addListener(resultPrinter);
+            // add all custom listeners
+            for (TestListener listener : mTestListeners) {
+                testRunResult.addListener(listener);
+            }
+
+            // run tests for realz!
+            for (TestCase testCase : testCases) {
+                prepareTestCase(testCase);
+                testCase.run(testRunResult);
+            }
+        } catch (Throwable t) {
+            // catch all exceptions so a more verbose error message can be outputted
+            resultPrinter.printUnexpectedError(t);
+            testRunOutput.putString("shortMsg", t.getMessage());
+        } finally {
+            long runTime = SystemClock.uptimeMillis() - startTime;
+            resultPrinter.print(testRunResult, runTime, testRunOutput);
+            automationWrapper.disconnect();
+            automationWrapper.setRunAsMonkey(false);
+            mHandlerThread.quit();
+        }
+    }
+
+    // copy & pasted from com.android.commands.am.Am
+    private class FakeInstrumentationWatcher implements IInstrumentationWatcher {
+
+        private final boolean mRawMode = true;
+
+        @Override
+        public IBinder asBinder() {
+            throw new UnsupportedOperationException("I'm just a fake!");
+        }
+
+        @Override
+        public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) {
+            synchronized (this) {
+                // pretty printer mode?
+                String pretty = null;
+                if (!mRawMode && results != null) {
+                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
+                }
+                if (pretty != null) {
+                    System.out.print(pretty);
+                } else {
+                    if (results != null) {
+                        for (String key : results.keySet()) {
+                            System.out.println("INSTRUMENTATION_STATUS: " + key + "="
+                                    + results.get(key));
+                        }
+                    }
+                    System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode);
+                }
+                notifyAll();
+            }
+        }
+
+        @Override
+        public void instrumentationFinished(ComponentName name, int resultCode, Bundle results) {
+            synchronized (this) {
+                // pretty printer mode?
+                String pretty = null;
+                if (!mRawMode && results != null) {
+                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
+                }
+                if (pretty != null) {
+                    System.out.println(pretty);
+                } else {
+                    if (results != null) {
+                        for (String key : results.keySet()) {
+                            System.out.println("INSTRUMENTATION_RESULT: " + key + "="
+                                    + results.get(key));
+                        }
+                    }
+                    System.out.println("INSTRUMENTATION_CODE: " + resultCode);
+                }
+                notifyAll();
+            }
+        }
+    }
+
+    private interface ResultReporter extends TestListener {
+        public void print(TestResult result, long runTime, Bundle testOutput);
+        public void printUnexpectedError(Throwable t);
+    }
+
+    // Copy & pasted from InstrumentationTestRunner.WatcherResultPrinter
+    private class WatcherResultPrinter implements ResultReporter {
+
+        private static final String REPORT_KEY_NUM_TOTAL = "numtests";
+        private static final String REPORT_KEY_NAME_CLASS = "class";
+        private static final String REPORT_KEY_NUM_CURRENT = "current";
+        private static final String REPORT_KEY_NAME_TEST = "test";
+        private static final String REPORT_KEY_NUM_ITERATIONS = "numiterations";
+        private static final String REPORT_VALUE_ID = "UiAutomatorTestRunner";
+        private static final String REPORT_KEY_STACK = "stack";
+
+        private static final int REPORT_VALUE_RESULT_START = 1;
+        private static final int REPORT_VALUE_RESULT_ERROR = -1;
+        private static final int REPORT_VALUE_RESULT_FAILURE = -2;
+
+        private final Bundle mResultTemplate;
+        Bundle mTestResult;
+        int mTestNum = 0;
+        int mTestResultCode = 0;
+        String mTestClass = null;
+
+        private final SimpleResultPrinter mPrinter;
+        private final ByteArrayOutputStream mStream;
+        private final PrintStream mWriter;
+
+        public WatcherResultPrinter(int numTests) {
+            mResultTemplate = new Bundle();
+            mResultTemplate.putString(Instrumentation.REPORT_KEY_IDENTIFIER, REPORT_VALUE_ID);
+            mResultTemplate.putInt(REPORT_KEY_NUM_TOTAL, numTests);
+
+            mStream = new ByteArrayOutputStream();
+            mWriter = new PrintStream(mStream);
+            mPrinter = new SimpleResultPrinter(mWriter, false);
+        }
+
+        /**
+         * send a status for the start of a each test, so long tests can be seen
+         * as "running"
+         */
+        @Override
+        public void startTest(Test test) {
+            String testClass = test.getClass().getName();
+            String testName = ((TestCase) test).getName();
+            mTestResult = new Bundle(mResultTemplate);
+            mTestResult.putString(REPORT_KEY_NAME_CLASS, testClass);
+            mTestResult.putString(REPORT_KEY_NAME_TEST, testName);
+            mTestResult.putInt(REPORT_KEY_NUM_CURRENT, ++mTestNum);
+            // pretty printing
+            if (testClass != null && !testClass.equals(mTestClass)) {
+                mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                        String.format("\n%s:", testClass));
+                mTestClass = testClass;
+            } else {
+                mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, "");
+            }
+
+            Method testMethod = null;
+            try {
+                testMethod = test.getClass().getMethod(testName);
+                // Report total number of iterations, if test is repetitive
+                if (testMethod.isAnnotationPresent(RepetitiveTest.class)) {
+                    int numIterations = testMethod.getAnnotation(RepetitiveTest.class)
+                            .numIterations();
+                    mTestResult.putInt(REPORT_KEY_NUM_ITERATIONS, numIterations);
+                }
+            } catch (NoSuchMethodException e) {
+                // ignore- the test with given name does not exist. Will be
+                // handled during test
+                // execution
+            }
+
+            mAutomationSupport.sendStatus(REPORT_VALUE_RESULT_START, mTestResult);
+            mTestResultCode = 0;
+
+            mPrinter.startTest(test);
+        }
+
+        @Override
+        public void addError(Test test, Throwable t) {
+            mTestResult.putString(REPORT_KEY_STACK, BaseTestRunner.getFilteredTrace(t));
+            mTestResultCode = REPORT_VALUE_RESULT_ERROR;
+            // pretty printing
+            mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                String.format("\nError in %s:\n%s",
+                    ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t)));
+
+            mPrinter.addError(test, t);
+        }
+
+        @Override
+        public void addFailure(Test test, AssertionFailedError t) {
+            mTestResult.putString(REPORT_KEY_STACK, BaseTestRunner.getFilteredTrace(t));
+            mTestResultCode = REPORT_VALUE_RESULT_FAILURE;
+            // pretty printing
+            mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                String.format("\nFailure in %s:\n%s",
+                    ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t)));
+
+            mPrinter.addFailure(test, t);
+        }
+
+        @Override
+        public void endTest(Test test) {
+            if (mTestResultCode == 0) {
+                mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, ".");
+            }
+            mAutomationSupport.sendStatus(mTestResultCode, mTestResult);
+
+            mPrinter.endTest(test);
+        }
+
+        @Override
+        public void print(TestResult result, long runTime, Bundle testOutput) {
+            mPrinter.print(result, runTime, testOutput);
+            testOutput.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                  String.format("\nTest results for %s=%s",
+                  getClass().getSimpleName(),
+                  mStream.toString()));
+            mWriter.close();
+            mAutomationSupport.sendStatus(Activity.RESULT_OK, testOutput);
+        }
+
+        @Override
+        public void printUnexpectedError(Throwable t) {
+            mWriter.println(String.format("Test run aborted due to unexpected exception: %s",
+                    t.getMessage()));
+            t.printStackTrace(mWriter);
+        }
+    }
+
+    /**
+     * Class that produces the same output as JUnit when running from command line. Can be
+     * used when default UiAutomator output is too verbose.
+     */
+    private class SimpleResultPrinter extends ResultPrinter implements ResultReporter {
+        private final boolean mFullOutput;
+        public SimpleResultPrinter(PrintStream writer, boolean fullOutput) {
+            super(writer);
+            mFullOutput = fullOutput;
+        }
+
+        @Override
+        public void print(TestResult result, long runTime, Bundle testOutput) {
+            printHeader(runTime);
+            if (mFullOutput) {
+                printErrors(result);
+                printFailures(result);
+            }
+            printFooter(result);
+        }
+
+        @Override
+        public void printUnexpectedError(Throwable t) {
+            if (mFullOutput) {
+                getWriter().printf("Test run aborted due to unexpected exeption: %s",
+                        t.getMessage());
+                t.printStackTrace(getWriter());
+            }
+        }
+    }
+
+    protected TestCaseCollector getTestCaseCollector(ClassLoader classLoader) {
+        return new TestCaseCollector(classLoader, getTestCaseFilter());
+    }
+
+    /**
+     * Returns an object which determines if the class and its methods should be
+     * accepted into the test suite.
+     * @return
+     */
+    public UiAutomatorTestCaseFilter getTestCaseFilter() {
+        return new UiAutomatorTestCaseFilter();
+    }
+
+    protected void addTestListener(TestListener listener) {
+        if (!mTestListeners.contains(listener)) {
+            mTestListeners.add(listener);
+        }
+    }
+
+    protected void removeTestListener(TestListener listener) {
+        mTestListeners.remove(listener);
+    }
+
+    /**
+     * subclass may override this method to perform further preparation
+     *
+     * @param testCase
+     */
+    protected void prepareTestCase(TestCase testCase) {
+        ((UiAutomatorTestCase)testCase).setAutomationSupport(mAutomationSupport);
+        ((UiAutomatorTestCase)testCase).setUiDevice(mUiDevice);
+        ((UiAutomatorTestCase)testCase).setParams(mParams);
+    }
+}
diff --git a/samples/SkeletonTest/Android.mk b/samples/SkeletonTest/Android.mk
new file mode 100644
index 0000000..a4a776f
--- /dev/null
+++ b/samples/SkeletonTest/Android.mk
@@ -0,0 +1,30 @@
+#Copyright (C) 2012 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.
+
+local_target_dir := $(TARGET_OUT_DATA)/local/tmp
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := uiautomator.skeletontest
+
+LOCAL_JAVA_LIBRARIES := uiautomator.core
+
+LOCAL_MODULE_PATH := $(local_target_dir)
+
+include $(BUILD_JAVA_LIBRARY)
diff --git a/samples/SkeletonTest/README b/samples/SkeletonTest/README
new file mode 100644
index 0000000..b402039
--- /dev/null
+++ b/samples/SkeletonTest/README
@@ -0,0 +1,19 @@
+This is an (almost) empty test, it serves as a prototype to create new UI
+Automator tests that can be compiled inside the Android build tree. The single
+test case included performs a key press, and send out some information about
+the test device.
+
+Steps to run this test:
+* have a fully built Android source tree
+* build the test:
+  mmm frameworks/testing/uiautomator/samples/SkeletonTest
+* deploy the test:
+  adb push ${OUT}/data/local/tmp/uiautomator.skeletontest.jar /data/local/tmp/
+* run the test:
+  adb shell uiautomator runtest uiautomator.skeletontest.jar \
+    -e class com.android.uiautomator.samples.skeleton.DemoTestCase
+
+Steps to create new tests off it:
+* cp -r frameworks/testing/uiautomator/samples/SkeletonTest /new/location
+* modify Android.mk, replace LOCAL_MODULE_NAME, change LOCAL_MODULE_TAGS if
+  necessary, add new dependecies if needed
diff --git a/samples/SkeletonTest/src/com/android/uiautomator/samples/skeleton/DemoTestCase.java b/samples/SkeletonTest/src/com/android/uiautomator/samples/skeleton/DemoTestCase.java
new file mode 100644
index 0000000..1abc25a
--- /dev/null
+++ b/samples/SkeletonTest/src/com/android/uiautomator/samples/skeleton/DemoTestCase.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 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.android.uiautomator.samples.skeleton;
+
+import android.app.Activity;
+import android.graphics.Point;
+import android.os.Bundle;
+
+import com.android.uiautomator.testrunner.UiAutomatorTestCase;
+
+public class DemoTestCase extends UiAutomatorTestCase {
+
+    public void testDemo() {
+        assertTrue(getUiDevice().pressHome());
+        Bundle status = new Bundle();
+        status.putString("msg", "This is a demo test and I just pressed HOME");
+        status.putString("product", getUiDevice().getProductName());
+        Point p = getUiDevice().getDisplaySizeDp();
+        status.putInt("dp-width", p.x);
+        status.putInt("dp-height", p.y);
+        getAutomationSupport().sendStatus(Activity.RESULT_OK, status);
+    }
+}
diff --git a/uiautomator_test_libraries/Android.mk b/uiautomator_test_libraries/Android.mk
new file mode 100644
index 0000000..f975016
--- /dev/null
+++ b/uiautomator_test_libraries/Android.mk
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2012 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.
+#
+local_target_dir := $(TARGET_OUT_DATA)/local/tmp
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := com.android.uiautomator.platform.common
+
+LOCAL_SDK_VERSION := 16
+
+LOCAL_JAVA_LIBRARIES := uiautomator_sdk_v$(LOCAL_SDK_VERSION)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(local_target_dir)
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/uiautomator_test_libraries/src/com/android/uiautomator/common/UiWatchers.java b/uiautomator_test_libraries/src/com/android/uiautomator/common/UiWatchers.java
new file mode 100644
index 0000000..dd1bb5b
--- /dev/null
+++ b/uiautomator_test_libraries/src/com/android/uiautomator/common/UiWatchers.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.common;
+
+import android.util.Log;
+
+import com.android.uiautomator.core.UiDevice;
+import com.android.uiautomator.core.UiObject;
+import com.android.uiautomator.core.UiObjectNotFoundException;
+import com.android.uiautomator.core.UiSelector;
+import com.android.uiautomator.core.UiWatcher;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class UiWatchers {
+    private static final String LOG_TAG = UiWatchers.class.getSimpleName();
+    private final List<String> mErrors = new ArrayList<String>();
+
+    /**
+     * We can use the UiDevice registerWatcher to register a small script to be executed when the
+     * framework is waiting for a control to appear. Waiting may be the cause of an unexpected
+     * dialog on the screen and it is the time when the framework runs the registered watchers.
+     * This is a sample watcher looking for ANR and crashes. it closes it and moves on. You should
+     * create your own watchers and handle error logging properly for your type of tests.
+     */
+    public void registerAnrAndCrashWatchers() {
+
+        UiDevice.getInstance().registerWatcher("ANR", new UiWatcher() {
+            @Override
+            public boolean checkForCondition() {
+                UiObject window = new UiObject(new UiSelector().className(
+                        "com.android.server.am.AppNotRespondingDialog"));
+                String errorText = null;
+                if (window.exists()) {
+                    try {
+                        errorText = window.getText();
+                    } catch (UiObjectNotFoundException e) {
+                        Log.e(LOG_TAG, "dialog gone?", e);
+                    }
+                    onAnrDetected(errorText);
+                    postHandler();
+                    return true; // triggered
+                }
+                return false; // no trigger
+            }
+        });
+
+        // class names may have changed
+        UiDevice.getInstance().registerWatcher("ANR2", new UiWatcher() {
+            @Override
+            public boolean checkForCondition() {
+                UiObject window = new UiObject(new UiSelector().packageName("android")
+                        .textContains("isn't responding."));
+                if (window.exists()) {
+                    String errorText = null;
+                    try {
+                        errorText = window.getText();
+                    } catch (UiObjectNotFoundException e) {
+                        Log.e(LOG_TAG, "dialog gone?", e);
+                    }
+                    onAnrDetected(errorText);
+                    postHandler();
+                    return true; // triggered
+                }
+                return false; // no trigger
+            }
+        });
+
+        UiDevice.getInstance().registerWatcher("CRASH", new UiWatcher() {
+            @Override
+            public boolean checkForCondition() {
+                UiObject window = new UiObject(new UiSelector().className(
+                        "com.android.server.am.AppErrorDialog"));
+                if (window.exists()) {
+                    String errorText = null;
+                    try {
+                        errorText = window.getText();
+                    } catch (UiObjectNotFoundException e) {
+                        Log.e(LOG_TAG, "dialog gone?", e);
+                    }
+                    onCrashDetected(errorText);
+                    postHandler();
+                    return true; // triggered
+                }
+                return false; // no trigger
+            }
+        });
+
+        UiDevice.getInstance().registerWatcher("CRASH2", new UiWatcher() {
+            @Override
+            public boolean checkForCondition() {
+                UiObject window = new UiObject(new UiSelector().packageName("android")
+                        .textContains("has stopped"));
+                if (window.exists()) {
+                    String errorText = null;
+                    try {
+                        errorText = window.getText();
+                    } catch (UiObjectNotFoundException e) {
+                        Log.e(LOG_TAG, "dialog gone?", e);
+                    }
+                    onCrashDetected(errorText);
+                    postHandler();
+                    return true; // triggered
+                }
+                return false; // no trigger
+            }
+        });
+
+        Log.i(LOG_TAG, "Registed GUI Exception watchers");
+    }
+
+    public void onAnrDetected(String errorText) {
+        mErrors.add(errorText);
+    }
+
+    public void onCrashDetected(String errorText) {
+        mErrors.add(errorText);
+    }
+
+    public void reset() {
+        mErrors.clear();
+    }
+
+    public List<String> getErrors() {
+        return Collections.unmodifiableList(mErrors);
+    }
+
+    /**
+     * Current implementation ignores the exception and continues.
+     */
+    public void postHandler() {
+        // TODO: Add custom error logging here
+
+        String formatedOutput = String.format("UI Exception Message: %-20s\n", UiDevice
+                .getInstance().getCurrentPackageName());
+        Log.e(LOG_TAG, formatedOutput);
+
+        UiObject buttonOK = new UiObject(new UiSelector().text("OK").enabled(true));
+        // sometimes it takes a while for the OK button to become enabled
+        buttonOK.waitForExists(5000);
+        try {
+            buttonOK.click();
+        } catch (UiObjectNotFoundException e) {
+            Log.e(LOG_TAG, "Exception", e);
+        }
+    }
+}
diff --git a/uiautomator_test_libraries/src/com/android/uiautomator/common/helpers/AppHelperBase.java b/uiautomator_test_libraries/src/com/android/uiautomator/common/helpers/AppHelperBase.java
new file mode 100644
index 0000000..e3d9b61
--- /dev/null
+++ b/uiautomator_test_libraries/src/com/android/uiautomator/common/helpers/AppHelperBase.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.common.helpers;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+
+/**
+ * Base app helper class intended for all app helper to extend.
+ * This class provides common APIs that are expected to be present across
+ * all app helpers.
+ */
+public abstract class AppHelperBase {
+
+    /*
+     * App helpers should provide methods for accessing various UI widgets.
+     * Assume the app has an Action Bar, the helper should provide something similar to
+     * SomeAppHelper.ActionBar.getRefreshButton(). Methods like this help the tests check the
+     * state of the targeted widget as well as clicking it if need be. These types of methods are
+     * referred to as object getters. If there are different components, consider creating internal
+     * name spaces as in the .ActionBar example for better context.
+     *
+     * Adding basic units of functionality APIs is also very helpful to test.
+     * Consider the Alarm clock application as an example. It would be helpful if its helper
+     * provided basic functionality such as, setAlarm(Date) and deleteAlarm(Date). Such basic
+     * and key functionality helper methods, will abstract the tests from the UI implementation and
+     * make tests more reliable.
+     */
+
+    /**
+     * Launches the application.
+     *
+     * This is typically performed by executing a shell command to launch the application
+     * via Intent. It is possible to launch the application by automating the Launcher
+     * views and finding the target app icon to launch, however, this is prone to failure if
+     * the Launcher UI implementation differ from one platform to another.
+     */
+    abstract public void open();
+
+    /**
+     * Checks if the application is in foreground.
+     *
+     * This is typically performed by verifying the current package name of the foreground
+     * application. See UiDevice.getCurrentPackageName()
+     * @return true if open, else false.
+     */
+    abstract public boolean isOpen();
+
+
+    /**
+     * Helper to execute a shell command.
+     * @param command
+     */
+    protected void runShellCommand(String command) {
+        Process p = null;
+        BufferedReader resultReader = null;
+        try {
+            p = Runtime.getRuntime().exec(command);
+            int status = p.waitFor();
+            if (status != 0) {
+                System.err.println(String.format("Run shell command: %s, status: %s", command,
+                        status));
+            }
+        } catch (IOException e) {
+            System.err.println("// Exception from command " + command + ":");
+            System.err.println(e.toString());
+        } catch (InterruptedException e) {
+            System.err.println("// Interrupted while waiting for the command to finish. ");
+            System.err.println(e.toString());
+        } finally {
+            try {
+                if (resultReader != null) {
+                    resultReader.close();
+                }
+                if (p != null) {
+                    p.destroy();
+                }
+            } catch (IOException e) {
+                System.err.println(e.toString());
+            }
+        }
+    }
+}
diff --git a/uiautomator_test_libraries/src/com/android/uiautomator/common/helpers/DatePickerHelper.java b/uiautomator_test_libraries/src/com/android/uiautomator/common/helpers/DatePickerHelper.java
new file mode 100644
index 0000000..6c7db3a
--- /dev/null
+++ b/uiautomator_test_libraries/src/com/android/uiautomator/common/helpers/DatePickerHelper.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.common.helpers;
+
+import com.android.uiautomator.core.UiObject;
+import com.android.uiautomator.core.UiObjectNotFoundException;
+import com.android.uiautomator.core.UiSelector;
+
+import java.util.Calendar;
+
+/**
+ * Use this helper anywhere there is a date picker to manage. This helper
+ * will set date specified in a Calendar object.
+ */
+public class DatePickerHelper {
+
+    public static final int MONTH = 0;
+    public static final int DAY = 1;
+    public static final int YEAR = 2;
+
+    public static String getCurrentMonth() throws UiObjectNotFoundException {
+        return getNumberPickerField(MONTH).getText();
+    }
+
+    public static String getCurrentDay() throws UiObjectNotFoundException {
+        return getNumberPickerField(DAY).getText();
+    }
+
+    public static String getCurrentYear() throws UiObjectNotFoundException {
+        return getNumberPickerField(YEAR).getText();
+    }
+
+    public static void incrementMonth() throws UiObjectNotFoundException {
+        incrementMonth(1);
+    }
+
+    public static void incrementMonth(int count) throws UiObjectNotFoundException {
+        for (int x = 0; x < count; x++)
+            getNumberPickerIncrementButton(MONTH).click();
+    }
+
+    public static void decrementMonth() throws UiObjectNotFoundException {
+        decrementMonth(1);
+    }
+
+    public static void decrementMonth(int count) throws UiObjectNotFoundException {
+        for (int x = 0; x < count; x++)
+            getNumberPickerDecrementButton(MONTH).click();
+    }
+
+    public static void incrementDay() throws UiObjectNotFoundException {
+        incrementDay(1);
+    }
+
+    public static void incrementDay(int count) throws UiObjectNotFoundException {
+        for (int x = 0; x < count; x++)
+            getNumberPickerIncrementButton(DAY).click();
+    }
+
+    public static void decrementDay() throws UiObjectNotFoundException {
+        decrementDay(1);
+    }
+
+    public static void decrementDay(int count) throws UiObjectNotFoundException {
+        for (int x = 0; x < count; x++)
+            getNumberPickerDecrementButton(DAY).click();
+    }
+
+    public static void incrementYear() throws UiObjectNotFoundException {
+        incrementYear(1);
+    }
+
+    public static void incrementYear(int count) throws UiObjectNotFoundException {
+        for (int x = 0; x < count; x++)
+            getNumberPickerIncrementButton(YEAR).click();
+    }
+
+    public static void decrementYear() throws UiObjectNotFoundException {
+        decrementYear(1);
+    }
+
+    public static void decrementYear(int count) throws UiObjectNotFoundException {
+        for (int x = 0; x < count; x++)
+            getNumberPickerDecrementButton(YEAR).click();
+    }
+
+    public static UiObject getNumberPicker(int instance) {
+        return new UiObject(new UiSelector().className(
+                android.widget.NumberPicker.class.getName()).instance(instance));
+    }
+
+    public static UiObject getNumberPickerField(int instance)
+            throws UiObjectNotFoundException {
+        return getNumberPicker(instance).getChild(
+                new UiSelector().className(android.widget.EditText.class.getName()));
+    }
+
+    public static UiObject getNumberPickerDecrementButton(int instance)
+            throws UiObjectNotFoundException {
+        return getNumberPicker(instance).getChild(
+                new UiSelector().className(android.widget.Button.class.getName()).instance(0));
+    }
+
+    public static UiObject getNumberPickerIncrementButton(int instance)
+            throws UiObjectNotFoundException {
+        return getNumberPicker(instance).getChild(
+                new UiSelector().className(android.widget.Button.class.getName()).instance(1));
+    }
+
+    public static void clickDone() throws UiObjectNotFoundException {
+        new UiObject(new UiSelector().text("Done")).click();
+    }
+
+    public static void setDate(Calendar cal) throws UiObjectNotFoundException {
+        int calYear = cal.get(Calendar.YEAR);
+        int calMonth = cal.get(Calendar.MONTH);
+        int calDay = cal.get(Calendar.DAY_OF_MONTH);
+
+        // Adjust day - increment or decrement using the shortest path
+        // while accounting for number of days in month and considering
+        // special case for Feb and leap years.
+        int dpDay = Integer.parseInt(getCurrentDay());
+        if (calDay > dpDay) {
+            if (calDay - dpDay < getDaysInMonth(calYear, calMonth) / 2)
+                incrementDay(calDay - dpDay);
+            else
+                decrementDay(dpDay - calDay + getDaysInMonth(calYear, calMonth));
+        } else if (dpDay > calDay) {
+            if (dpDay - calDay < getDaysInMonth(calYear, calMonth) / 2)
+                decrementDay(dpDay - calDay);
+            else
+                incrementDay(calDay - dpDay + getDaysInMonth(calYear, calMonth));
+        }
+
+        // Adjust month - increment or decrement using the shortest path
+        int dpMonth = toMonthNumber(getCurrentMonth());
+        if (calMonth > dpMonth) {
+            if (calMonth - dpMonth < 6)
+                incrementMonth(calMonth - dpMonth);
+            else
+                decrementMonth(dpMonth - calMonth + 12);
+        } else if (dpMonth > calMonth) {
+            if (dpMonth - calMonth < 6)
+                decrementMonth(dpMonth - calMonth);
+            else
+                incrementMonth(calMonth - dpMonth + 12);
+        }
+
+        // Adjust year
+        int dpYear = Integer.parseInt(getCurrentYear());
+        if (calYear > dpYear) {
+            incrementYear(calYear - dpYear);
+        } else if (dpYear > calYear) {
+            decrementYear(dpYear - calYear);
+        }
+    }
+
+    private static int toMonthNumber(String monthName) {
+        String months[] = new String[] {"January", "February", "March", "April", "May", "June",
+                "July", "August", "September", "October", "November", "December"};
+
+        for (int x = 0; x < months.length; x++) {
+            if (months[x].contains(monthName))
+                return x;
+        }
+
+        return 0;
+    }
+
+    /**
+     * Get the number of days in the month
+     * @param year
+     * @param month
+     * @return
+     */
+    private static int getDaysInMonth(int year, int month) {
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.YEAR, year);
+        cal.set(Calendar.MONTH, month);
+        return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+    }
+}
diff --git a/uiautomator_test_libraries/src/com/android/uiautomator/common/helpers/TimePickerHelper.java b/uiautomator_test_libraries/src/com/android/uiautomator/common/helpers/TimePickerHelper.java
new file mode 100644
index 0000000..c5e3add
--- /dev/null
+++ b/uiautomator_test_libraries/src/com/android/uiautomator/common/helpers/TimePickerHelper.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.common.helpers;
+
+import com.android.uiautomator.core.UiObject;
+import com.android.uiautomator.core.UiObjectNotFoundException;
+import com.android.uiautomator.core.UiSelector;
+
+import java.util.Calendar;
+import java.util.Locale;
+
+/**
+ * Use this helper anywhere there is a time picker to manage. This helper
+ * will set time specified in a Calendar object.
+ */
+public class TimePickerHelper {
+
+    public static final int HOUR = 0;
+    public static final int MINUTE = 1;
+    public static final int MERIDIEM = 2;
+
+    public static String getCurrentHour() throws UiObjectNotFoundException {
+        return getNumberPickerField(HOUR).getText();
+    }
+
+    public static String getCurrentMinute() throws UiObjectNotFoundException {
+        return getNumberPickerField(MINUTE).getText();
+    }
+
+    public static String getCurrentMeridiem() throws UiObjectNotFoundException {
+        return getNumberPickerField(MERIDIEM).getText();
+    }
+
+
+    public static void incrementHour() throws UiObjectNotFoundException {
+        incrementHour(1);
+    }
+
+    public static void incrementHour(int count) throws UiObjectNotFoundException {
+        for (int x = 0; x < count; x++)
+            getNumberPickerIncrementButton(HOUR).click();
+    }
+
+    public static void decrementHour() throws UiObjectNotFoundException {
+        decrementHour(1);
+    }
+
+    public static void decrementHour(int count) throws UiObjectNotFoundException {
+        for (int x = 0; x < count; x++)
+            getNumberPickerDecrementButton(HOUR).click();
+    }
+
+    public static void incrementMinute() throws UiObjectNotFoundException {
+        incrementMinute(1);
+    }
+
+    public static void incrementMinute(int count) throws UiObjectNotFoundException {
+        for (int x = 0; x < count; x++)
+            getNumberPickerIncrementButton(MINUTE).click();
+    }
+
+    public static void decrementMinute() throws UiObjectNotFoundException {
+        decrementMinute(1);
+    }
+
+    public static void decrementMinute(int count) throws UiObjectNotFoundException {
+        for (int x = 0; x < count; x++)
+            getNumberPickerDecrementButton(MINUTE).click();
+    }
+
+    public static void selectPM() throws UiObjectNotFoundException {
+        getNumberPicker(MERIDIEM).getChild(new UiSelector().text("PM")).click();
+    }
+
+    public static void selectAM() throws UiObjectNotFoundException {
+        getNumberPicker(MERIDIEM).getChild(new UiSelector().text("AM")).click();
+    }
+
+    public static UiObject getNumberPicker(int instance) {
+        return new UiObject(new UiSelector().className(
+                android.widget.NumberPicker.class.getName()).instance(instance));
+    }
+
+    public static UiObject getNumberPickerField(int instance)
+            throws UiObjectNotFoundException {
+        return getNumberPicker(instance).getChild(
+                new UiSelector().className(android.widget.EditText.class.getName()));
+    }
+
+    public static UiObject getNumberPickerDecrementButton(int instance)
+            throws UiObjectNotFoundException {
+        return getNumberPicker(instance).getChild(
+                new UiSelector().className(android.widget.Button.class.getName()).instance(0));
+    }
+
+    public static UiObject getNumberPickerIncrementButton(int instance)
+            throws UiObjectNotFoundException {
+        return getNumberPicker(instance).getChild(
+                new UiSelector().className(android.widget.Button.class.getName()).instance(1));
+    }
+
+    public static void clickDone() throws UiObjectNotFoundException {
+        new UiObject(new UiSelector().text("Done")).click();
+    }
+
+    public static void setTime(Calendar cal) throws UiObjectNotFoundException {
+        // Adjust minutes - increment or decrement using the shortest path
+        int tpMinute = Integer.parseInt(getCurrentMinute());
+        int calMinute = cal.get(Calendar.MINUTE);
+        if (calMinute > tpMinute) {
+            if (calMinute - tpMinute < 30)
+                incrementMinute(calMinute - tpMinute);
+            else
+                decrementMinute(tpMinute - calMinute + 60);
+        } else if (tpMinute > calMinute) {
+            if (tpMinute - calMinute < 30)
+                decrementMinute(tpMinute - calMinute);
+            else
+                incrementMinute(calMinute - tpMinute + 60);
+        }
+
+        // Adjust hour - increment or decrement using the shortest path
+        int tpHour = Integer.parseInt(getCurrentHour());
+        int calHour = cal.get(Calendar.HOUR);
+        if (calHour > tpHour) {
+            if (calHour - tpHour < 6)
+                incrementHour(calHour - tpHour);
+            else
+                decrementHour(tpHour - calHour + 12);
+        } else if (tpHour > calHour) {
+            if (tpHour - calHour < 6)
+                decrementHour(tpHour - calHour);
+            else
+                incrementHour(calHour - tpHour + 12);
+        }
+
+        // Adjust meridiem
+        String calMer = cal.getDisplayName(Calendar.AM_PM, Calendar.SHORT, Locale.US);
+        String tpMer = getCurrentMeridiem();
+        if (tpMer.equalsIgnoreCase(calMer))
+            return;
+
+        if (!calMer.equalsIgnoreCase("AM")) {
+            selectPM();
+        } else {
+            selectAM();
+        }
+    }
+}
diff --git a/uiautomator_test_libraries/src/com/android/uiautomator/platform/JankTestBase.java b/uiautomator_test_libraries/src/com/android/uiautomator/platform/JankTestBase.java
new file mode 100644
index 0000000..6662f80
--- /dev/null
+++ b/uiautomator_test_libraries/src/com/android/uiautomator/platform/JankTestBase.java
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.platform;
+
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+
+import com.android.uiautomator.core.UiDevice;
+import com.android.uiautomator.testrunner.UiAutomatorTestCase;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Base class for jank test.
+ * All jank test needs to extend JankTestBase
+ */
+public class JankTestBase extends UiAutomatorTestCase {
+    private static final String TAG = JankTestBase.class.getSimpleName();
+
+    protected UiDevice mDevice;
+    protected TestWatchers mTestWatchers = null;
+    protected BufferedWriter mWriter = null;
+    protected BufferedWriter mStatusWriter = null;
+    protected int mIteration = 20; // default iteration is set 20
+    /* can be used to enable/disable systrace in the test */
+    protected int mTraceTime = 0;
+    protected Bundle mParams;
+    protected String mTestCaseName;
+    protected int mSuccessTestRuns = 0;
+    protected Thread mThread = null;
+
+    // holds all params for the derived tests
+    private static final String PROPERTY_FILE_NAME = "UiJankinessTests.conf";
+    private static final String PARAM_CONFIG = "conf";
+    private static final String LOCAL_TMP_DIR = "/data/local/tmp/";
+    // File that hold the test results
+    private static String OUTPUT_FILE_NAME = LOCAL_TMP_DIR + "UiJankinessTestsOutput.txt";
+    // File that hold test status, e.g successful test iterations
+    private static String STATUS_FILE_NAME = LOCAL_TMP_DIR + "UiJankinessTestsStatus.txt";
+    private static final String RAW_DATA_DIR = LOCAL_TMP_DIR + "UiJankinessRawData";
+
+    private static int SUCCESS_THRESHOLD = 80;
+    private static boolean DEBUG = false;
+
+    /* default animation time is set to 2 seconds */
+    protected static final long DEFAULT_ANIMATION_TIME = 2 * 1000;
+    /* default swipe steps for fling animation */
+    protected static final int DEFAULT_FLING_STEPS = 8;
+
+    /* Array to record jankiness data in each test iteration */
+    private int[] jankinessArray;
+    /* Array to record frame rate in each test iteration */
+    private double[] frameRateArray;
+    /* Array to save max accumulated frame number in each test iteration */
+    private int[] maxDeltaVsyncArray;
+    /* Default file to store the systrace */
+    private static final File SYSTRACE_DIR = new File(LOCAL_TMP_DIR, "systrace");
+    /* Default trace file name */
+    private static final String TRACE_FILE_NAME = "trace.txt";
+    /* Default tracing time is 5 seconds */
+    private static final int DEFAULT_TRACE_TIME = 5; // 5 seconds
+    // Command to dump compressed trace data
+    private static final String ATRACE_COMMAND = "atrace -z -t %d gfx input view sched freq";
+
+    /**
+     * Thread to capture systrace log from the test
+     */
+    public class SystraceTracker implements Runnable {
+        File mFile = new File(SYSTRACE_DIR, TRACE_FILE_NAME);
+        int mTime = DEFAULT_TRACE_TIME;
+
+        public SystraceTracker(int traceTime, String fileName) {
+            try {
+                if (!SYSTRACE_DIR.exists()) {
+                    if (!SYSTRACE_DIR.mkdir()) {
+                        log(String.format("create directory %s failed, you can manually create "
+                                + "it and start the test again", SYSTRACE_DIR.getAbsolutePath()));
+                        return;
+                    }
+                }
+            } catch (SecurityException e) {
+                Log.e(TAG, "creating directory failed?", e);
+            }
+
+            if (traceTime > 0) {
+                mTime = traceTime;
+            }
+            if (fileName != null) {
+                mFile = new File(SYSTRACE_DIR, fileName);
+            }
+        }
+
+        @Override
+        public void run() {
+            String command = String.format(ATRACE_COMMAND, mTime);
+            Log.v(TAG, "command: " + command);
+            Process p = null;
+            InputStream in = null;
+            BufferedOutputStream out = null;
+            try {
+                p = Runtime.getRuntime().exec(command);
+                Log.v(TAG, "write systrace into file: " + mFile.getAbsolutePath());
+                // read bytes from the process output stream as the output is compressed
+                byte[] buffer = new byte[1024];
+                in = p.getInputStream();
+                out = new BufferedOutputStream(new FileOutputStream(mFile));
+                int n;
+                while ((n = in.read(buffer)) != -1) {
+                    out.write(buffer, 0, n);
+                    out.flush();
+                }
+                in.close();
+                out.close();
+                // read error message
+                BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
+                String line;
+                while ((line = br.readLine()) != null) {
+                    Log.e(TAG, "Command return errors: " + line);
+                }
+                br.close();
+
+                // Due to limited buffer size for standard input and output stream,
+                // promptly reading from the input stream or output stream to avoid block
+                int status = p.waitFor();
+                if (status != 0) {
+                    Log.e(TAG, String.format("Run shell command: %s, status: %s",
+                            command, status));
+                }
+            } catch (InterruptedException e) {
+                Log.e(TAG, "Exception from command " + command + ":");
+                Log.e(TAG, "Thread interrupted? ", e);
+            } catch (IOException e) {
+                Log.e(TAG, "Open file error: ", e);
+            } catch (IllegalThreadStateException e) {
+                Log.e(TAG, "the process has not exit yet ", e);
+            }
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDevice = UiDevice.getInstance();
+        mTestWatchers = new TestWatchers(); // extends the common class UiWatchers
+        mTestWatchers.registerAnrAndCrashWatchers();
+
+        mWriter = new BufferedWriter(new FileWriter(new File(OUTPUT_FILE_NAME), true));
+        mStatusWriter = new BufferedWriter(new FileWriter(new File(STATUS_FILE_NAME), true));
+
+        mParams = getParams();
+        if (mParams != null && !mParams.isEmpty()) {
+            log("mParams is not empty, get properties.");
+            String mIterationStr = getPropertyString(mParams, "iteration");
+            if (mIterationStr != null) {
+                mIteration = Integer.valueOf(mIterationStr);
+            }
+            String mTraceTimeStr = getPropertyString(mParams, "tracetime");
+            if (mTraceTimeStr  != null) {
+                mTraceTime = Integer.valueOf(mTraceTimeStr);
+            }
+        }
+        jankinessArray = new int[mIteration];
+        frameRateArray = new double[mIteration];
+        maxDeltaVsyncArray = new int[mIteration];
+        mTestCaseName = this.getName();
+
+        mSuccessTestRuns = 0;
+        mDevice.pressHome();
+    }
+
+    /**
+     * Create a new thread for systrace and start the thread
+     *
+     * @param testCaseName
+     * @param iteration
+     */
+    protected void startTrace(String testCaseName, int iteration) {
+        if (mTraceTime > 0) {
+            String outputFile = String.format("%s_%d_trace", mTestCaseName, iteration);
+            mThread = new Thread(new SystraceTracker(mTraceTime, outputFile));
+            mThread.start();
+        }
+    }
+
+    /**
+     * Wait for the tracing thread to exit
+     */
+    protected void endTrace() {
+        if (mThread != null) {
+            try {
+                mThread.join();
+            } catch (InterruptedException e) {
+                Log.e(TAG, "wait for the trace thread to exit exception:", e);
+            }
+        }
+    }
+
+    /**
+     * Expects a file from the command line via conf param or default following format each on its
+     * own line. <code>
+     *    key=Value
+     *    Browser_URL1=cnn.com
+     *    Browser_URL2=google.com
+     *    Camera_ShutterDelay=1000
+     *    etc...
+     * </code>
+     * @param Bundle params
+     * @param key
+     * @return the value of the property else defaultValue
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+    protected String getPropertyString(Bundle params, String key)
+            throws FileNotFoundException, IOException {
+        Properties prop = new Properties();
+        prop.load(new FileInputStream(new File(LOCAL_TMP_DIR,
+                params.getString(PARAM_CONFIG, PROPERTY_FILE_NAME))));
+        String value = prop.getProperty(key);
+        if (value != null && !value.isEmpty())
+            return value;
+        return null;
+    }
+
+    /**
+     * Expects a file from the command line via conf param or default following format each on its
+     * own line. <code>
+     *    key=Value
+     *    Browser_URL1=cnn.com
+     *    Browser_URL2=google.com
+     *    Camera_ShutterDelay=1000
+     *    etc...
+     * </code>
+     * @param Bundle params
+     * @param key
+     * @return the value of the property else defaultValue
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+    protected long getPropertyLong(Bundle params, String key)
+            throws FileNotFoundException, IOException {
+        Properties prop = new Properties();
+        prop.load(new FileInputStream(new File(LOCAL_TMP_DIR,
+                params.getString(PARAM_CONFIG, PROPERTY_FILE_NAME))));
+        String value = prop.getProperty(key);
+        if (value != null && !value.trim().isEmpty())
+            return Long.valueOf(value.trim());
+        return 0;
+    }
+
+    /**
+     * Verify the test result by comparing data sample size with expected value
+     * @param expectedDataSize the expected data size
+     */
+    protected boolean validateResults(int expectedDataSize) {
+        int receivedDataSize = SurfaceFlingerHelper.getDataSampleSize();
+        return ((expectedDataSize > 0) && (receivedDataSize >= expectedDataSize));
+    }
+
+    /**
+     * Process the raw data, calculate jankiness, frame rate and max accumulated frames number
+     * @param testCaseName
+     * @param iteration
+     */
+    protected void recordResults(String testCaseName, int iteration) {
+        long refreshPeriod = SurfaceFlingerHelper.getRefreshPeriod();
+        // if the raw directory doesn't exit, create the directory
+        File rawDataDir = new File(RAW_DATA_DIR);
+        try {
+            if (!rawDataDir.exists()) {
+                if (!rawDataDir.mkdir()) {
+                    log(String.format("create directory %s failed, you can manually create " +
+                            "it and start the test again", rawDataDir));
+                }
+            }
+        } catch (SecurityException e) {
+            Log.e(TAG, "create directory failed: ", e);
+        }
+        String rawFileName = String.format("%s/%s_%d.txt", RAW_DATA_DIR, testCaseName, iteration);
+        // write results into a file
+        BufferedWriter fw = null;
+        try {
+            fw = new BufferedWriter(new FileWriter(new File(rawFileName), false));
+            fw.write(SurfaceFlingerHelper.getFrameBufferData());
+        } catch (IOException e) {
+            Log.e(TAG, "failed to write to file", e);
+            return;
+        } finally {
+            try {
+                if (fw != null) {
+                    fw.close();
+                }
+            }
+            catch (IOException e) {
+                    Log.e(TAG, "close file failed.", e);
+            }
+        }
+
+        // get jankiness count
+        int jankinessCount = SurfaceFlingerHelper.getVsyncJankiness();
+        // get frame rate
+        double frameRate = SurfaceFlingerHelper.getFrameRate();
+        // get max accumulated frames
+        int maxDeltaVsync = SurfaceFlingerHelper.getMaxDeltaVsync();
+
+        // only record data when they are valid
+        if (jankinessCount >=0 && frameRate > 0) {
+            jankinessArray[iteration] = jankinessCount;
+            frameRateArray[iteration] = frameRate;
+            maxDeltaVsyncArray[iteration] = maxDeltaVsync;
+            mSuccessTestRuns++;
+        }
+        String msg = String.format("%s, iteration %d\n" +
+                "refresh period: %d\n" +
+                "jankiness count: %d\n" +
+                "frame rate: %f\n" +
+                "max accumulated frames: %d\n",
+                testCaseName, iteration, refreshPeriod,
+                jankinessCount, frameRate, maxDeltaVsync);
+        log(msg);
+        if (DEBUG) {
+            SurfaceFlingerHelper.printData(testCaseName, iteration);
+        }
+    }
+
+    /**
+     * Process data from all test iterations, and save to disk
+     * @param testCaseName
+     */
+    protected void saveResults(String testCaseName) {
+        // write test status into status file
+        try {
+            mStatusWriter.write(String.format("%s: %d success runs out of %d iterations\n",
+                    testCaseName, mSuccessTestRuns, mIteration));
+        } catch (IOException e) {
+            log("failed to write output for test case " + testCaseName);
+        }
+
+        // if successful test runs is less than the threshold, no results will be saved.
+        if (mSuccessTestRuns * 100 / mIteration < SUCCESS_THRESHOLD) {
+            log(String.format("In %s, # of successful test runs out of %s iterations: %d ",
+                    testCaseName, mIteration, mSuccessTestRuns));
+            log(String.format("threshold is %d%%", SUCCESS_THRESHOLD));
+            return;
+        }
+
+        if (DEBUG) {
+            print(jankinessArray, "jankiness array");
+            print(frameRateArray, "frame rate array");
+            print(maxDeltaVsyncArray, "max delta vsync array");
+        }
+        double avgJankinessCount = getAverage(jankinessArray);
+        int maxJankinessCount = getMaxValue(jankinessArray);
+        double avgFrameRate = getAverage(frameRateArray);
+        double avgMaxDeltaVsync = getAverage(maxDeltaVsyncArray);
+
+        String avgMsg = String.format("%s\n" +
+                "average number of jankiness: %f\n" +
+                "max number of jankiness: %d\n" +
+                "average frame rate: %f\n" +
+                "average of max accumulated frames: %f\n",
+                testCaseName, avgJankinessCount, maxJankinessCount, avgFrameRate, avgMaxDeltaVsync);
+        log(avgMsg);
+
+        try {
+            mWriter.write(avgMsg);
+        } catch (IOException e) {
+            log("failed to write output for test case " + testCaseName);
+        }
+    }
+
+    // return the max value in an integer array
+    private int getMaxValue(int[] intArray) {
+        int index = 0;
+        int max = intArray[index];
+        for (int i  = 1; i < intArray.length; i++) {
+            if (max < intArray[i]) {
+                max = intArray[i];
+            }
+        }
+        return max;
+    }
+
+    private double getAverage(int[] intArray) {
+        int mean = 0;
+        int numberTests = 0;
+        for (int i = 0; i < intArray.length; i++) {
+            // in case in some iteration, test fails, no data points is collected
+            if (intArray[i] >= 0) {
+                mean += intArray[i];
+                ++numberTests;
+            }
+        }
+        return (double)mean/numberTests;
+    }
+
+    private double getAverage(double[] doubleArray) {
+        double mean = 0;
+        int numberTests = 0;
+        for (int i = 0; i < doubleArray.length; i++) {
+            // in case in some iteration, test fails, no data points is collected
+            if (doubleArray[i] >= 0) {
+                mean += doubleArray[i];
+                ++numberTests;
+            }
+        }
+        return mean/numberTests;
+    }
+
+    private void print(int[] intArray, String arrayName) {
+        log("start to print array for " + arrayName);
+        for (int i = 0; i < intArray.length; i++) {
+            log(String.format("%d: %d", i, intArray[i]));
+        }
+    }
+
+    private void print(double[] doubleArray, String arrayName) {
+        log("start to print array for " + arrayName);
+        for (int i = 0; i < doubleArray.length; i++) {
+            log(String.format("%d: %f", i, doubleArray[i]));
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        if (mWriter != null) {
+            mWriter.close();
+        }
+        if (mStatusWriter != null) {
+            mStatusWriter.close();
+        }
+    }
+
+   private void log(String message) {
+       Log.v(TAG, message);
+   }
+
+   /**
+    * Set the total number of test iteration
+    * @param iteration
+    */
+   protected void setIteration(int iteration){
+       mIteration = iteration;
+   }
+
+   /**
+    * Get the total number of test iteration
+    * @return iteration
+    */
+   protected int getIteration(){
+       return mIteration;
+   }
+}
diff --git a/uiautomator_test_libraries/src/com/android/uiautomator/platform/SurfaceFlingerHelper.java b/uiautomator_test_libraries/src/com/android/uiautomator/platform/SurfaceFlingerHelper.java
new file mode 100644
index 0000000..748b433
--- /dev/null
+++ b/uiautomator_test_libraries/src/com/android/uiautomator/platform/SurfaceFlingerHelper.java
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.platform;
+
+import android.os.Environment;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.BufferedWriter;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.lang.Math;
+
+/*
+ * Tools to measure jankiness through SurfaceFlinger
+ */
+public class SurfaceFlingerHelper {
+    private static String TAG = "SurfaceFlingerHelper";
+    private static int BUFFER_SIZE = 128;
+    private static int BUFFER_NUMBER = 3;
+    private static String CLEAR_BUFFER_CMD = "dumpsys SurfaceFlinger --latency-clear";
+    private static String FRAME_LATENCY_CMD = "dumpsys SurfaceFlinger --latency";
+    private static final String RAW_DATA_DIR = "UiJankinessRawData";
+    private static final String LOCAL_TMP_DIR = "/data/local/tmp/";
+    /* If the latency between two frames is greater than this number, it it treated as a pause
+     * not a jankiness */
+    private static final int PAUSE_LATENCY = 20;
+
+    /* An array list which includes the raw buffer information from frame latency tool */
+    private static List<List<String>> mFrameBufferData = new ArrayList<List<String>>(BUFFER_SIZE);
+
+    /* Record the refresh period returned from driver */
+    private static long mRefreshPeriod = -1;
+
+    /* Record the size of frame latency */
+    private static int mFrameLatencySampleSize = 0;
+
+    /* An integer array which includes delta vsync */
+    private static long[] mDeltaVsync = new long[BUFFER_SIZE];
+
+    /* Integer array for delta of delta vsync */
+    private static long[] mDelta2Vsync = new long[BUFFER_SIZE];
+
+    /* the maximum delta vsync number */
+    private static long mMaxDeltaVsync;
+
+    /* Normalized data */
+    private static double[] mNormalizedDelta2Vsync = new double[BUFFER_SIZE];
+    private static int[] mRoundNormalizedDelta2Vsync = new int[BUFFER_SIZE];
+    // Symbol of unfinished frame time */
+    public static final String PENDING_FENCE_TIME = new Long(Long.MAX_VALUE).toString();
+
+    /**
+     * Run clear buffer command and clear the saved frame buffer results
+     *
+     * @param windowName the window name that the buffer will be cleared
+     */
+    public static void clearBuffer(String windowName) {
+        // clear results
+        if (mFrameBufferData != null) {
+            mFrameBufferData.clear();
+        }
+        Arrays.fill(mDeltaVsync, -1);
+        Arrays.fill(mDelta2Vsync, -1);
+        Arrays.fill(mNormalizedDelta2Vsync, -1.0);
+        Arrays.fill(mRoundNormalizedDelta2Vsync, -1);
+        mRefreshPeriod = -1;
+        mFrameLatencySampleSize = 0;
+        mMaxDeltaVsync = 0;
+
+        Process p = null;
+        BufferedReader resultReader = null;
+        String command = CLEAR_BUFFER_CMD;
+        if (windowName != null) {
+            command = String.format("%s %s", CLEAR_BUFFER_CMD, windowName);
+        }
+        try {
+            p = Runtime.getRuntime().exec(command);
+            int status = p.waitFor();
+            if (status != 0) {
+                Log.e(TAG, String.format("Run shell command: %s, status: %s",
+                        command, status));
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "// Exception from command " + command + ":", e);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "// Interrupted while waiting for the command to finish. ", e);
+        } finally {
+            try {
+                if (resultReader != null) {
+                    resultReader.close();
+                }
+                if (p != null) {
+                    p.destroy();
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "exception " + e);
+            }
+        }
+    }
+
+    /**
+     * Run frame latency command without ignoring pending fence time
+     *
+     * @param windowName the window name which SurfaceFlinger will acquire frame time for
+     */
+    public static boolean dumpFrameLatency(String windowName) {
+        return dumpFrameLatency(windowName, false);
+    }
+
+    /**
+     * Run frame latency command to get frame time
+     *
+     * @param windowName the window name which SurfaceFlinger will get frame time for
+     * @param ignorePendingFenceTime flag to process frames with pending fence time
+     *                              set true to ignore pending fence time
+     *                              set false to fail the test if pending fence time is not allowed
+     */
+    public static boolean dumpFrameLatency(String windowName, boolean ignorePendingFenceTime) {
+        Process p = null;
+        BufferedReader resultReader = null;
+        String command = FRAME_LATENCY_CMD;
+        if (windowName != null) {
+            command = String.format("%s %s", FRAME_LATENCY_CMD, windowName);
+        }
+        log("dump frame latency command: " + command);
+        try {
+            p = Runtime.getRuntime().exec(command);
+            int status = p.waitFor();
+            if (status != 0) {
+                Log.e(TAG, String.format("Run shell command: %s, status: %s",command, status));
+            }
+            resultReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
+            String line = resultReader.readLine();
+            mRefreshPeriod = Long.parseLong(line.trim());
+            log("reading refresh period: " + mRefreshPeriod);
+            if (mRefreshPeriod < 0) {
+                return false;
+            }
+            boolean dataInvalidFlag = false;
+            while((line = resultReader.readLine()) != null) {
+                // remove lines which are empty
+                if (line.trim().isEmpty()) {
+                    break;
+                }
+                String[] bufferValues = line.split("\\s+");
+                if (bufferValues[0].trim().compareTo("0") == 0) {
+                    continue;
+                } else if (bufferValues[1].trim().compareTo(PENDING_FENCE_TIME) == 0 ) {
+                    if (ignorePendingFenceTime) {
+                        log("ignore pending fence time");
+                        dataInvalidFlag = true;
+                    } else {
+                        log("the data contains unfinished frame time, please allow the animation"
+                            + " to finish in the test before calling dumpFrameLatency.");
+                        return false;
+                    }
+                }
+                // store raw data which could have both valid and invalid data
+                List<String> delayArray = Arrays.asList(bufferValues);
+                mFrameBufferData.add(delayArray);
+                if (!dataInvalidFlag) {
+                    // only count frames which have valid time
+                    ++mFrameLatencySampleSize;
+                }
+            }
+            log("frame latency sample size: " + mFrameLatencySampleSize);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "// Exception from command " + command + ":", e);
+        } catch (IOException e) {
+            Log.e(TAG, "Open file error: ", e);
+            return false;
+        }
+        finally {
+            try {
+                if (resultReader != null) {
+                    resultReader.close();
+                }
+                if (p != null) {
+                    p.destroy();
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "io exception: ", e);
+            }
+        }
+        return true;
+    }
+
+    public static int getDataSampleSize() {
+        return mFrameLatencySampleSize;
+    }
+
+    public static long getRefreshPeriod() {
+        if (mRefreshPeriod < 0) {
+            // Haven't dump the frame latency yet
+            log("Run command \"" + FRAME_LATENCY_CMD + " \" before retrieving the refresh period");
+        }
+        return mRefreshPeriod;
+    }
+
+    public static String getFrameBufferData() {
+        if (mFrameBufferData.get(0) == null) {
+            log("Run command \"" + FRAME_LATENCY_CMD + " \" before retrieving frame buffer data");
+            return null;
+        }
+        String rawData = String.format("%d\n", mRefreshPeriod);
+        List<String> tempList = new ArrayList<String>(BUFFER_NUMBER);
+        for (int i = 0; i < mFrameBufferData.size(); i++) {
+            tempList = mFrameBufferData.get(i);
+            for (int j = 0; j < BUFFER_NUMBER; j++) {
+                rawData += String.format("%s", tempList.get(j));
+                if (j < BUFFER_NUMBER - 1) {
+                    rawData += "\t";
+                } else {
+                    rawData += "\n";
+                }
+            }
+        }
+        return rawData;
+    }
+
+    /**
+     * Calculate delta(vsync)
+     * @return
+     */
+    public static long[] getDeltaVsync() {
+        if (mRefreshPeriod < 0) {
+            log("Run command \"" + FRAME_LATENCY_CMD + " \" before retrieving frame latency");
+            return null;
+        }
+        if (mDeltaVsync[0] < 0 ) {
+            // keep a record of the max DeltaVsync
+            mMaxDeltaVsync = 0;
+            // get the first frame vsync time
+            long preVsyncTime = Long.parseLong(mFrameBufferData.get(0).get(1));
+            for (int i = 0; i < mFrameLatencySampleSize - 1; i++) {
+                long curVsyncTime = Long.parseLong(mFrameBufferData.get(i + 1).get(1));
+                mDeltaVsync[i] = curVsyncTime - preVsyncTime;
+                preVsyncTime = curVsyncTime;
+                if (mMaxDeltaVsync < mDeltaVsync[i]) {
+                    mMaxDeltaVsync = mDeltaVsync[i];
+                }
+            }
+        }
+        return mDeltaVsync;
+    }
+
+    /**
+     * Calculate difference between delta vsync
+     * @return
+     */
+    public static long[] getDelta2Vsync() {
+        if (mRefreshPeriod < 0) {
+            log("Run command \"" + FRAME_LATENCY_CMD + " \" before retrieving frame latency");
+            return null;
+        }
+        if (mDeltaVsync[0] < 0) {
+            getDeltaVsync();
+        }
+        if (mDelta2Vsync[0] < 0) {
+            int numDeltaVsync = mFrameLatencySampleSize - 1;
+            for (int i = 0; i < numDeltaVsync - 1; i++) {
+                mDelta2Vsync[i] = mDeltaVsync[i + 1] - mDeltaVsync[i];
+            }
+        }
+        return mDelta2Vsync;
+    }
+
+    /**
+     * normalized delta(delta(vsync)) by refresh period
+     * @return
+     */
+    public static double[] getNormalizedDelta2Vsync() {
+        if (mRefreshPeriod < 0) {
+            log("Run command \"" + FRAME_LATENCY_CMD + " \" before retrieving frame latency");
+            return null;
+        }
+        if (mDelta2Vsync[0] < 0) {
+            getDelta2Vsync();
+        }
+        if (mNormalizedDelta2Vsync[0] < 0) {
+            for (int i = 0; i < mFrameLatencySampleSize - 2; i++) {
+                mNormalizedDelta2Vsync[i] = (double)mDelta2Vsync[i] /mRefreshPeriod;
+            }
+        }
+        return mNormalizedDelta2Vsync;
+    }
+
+    public static int[] getRoundNormalizedDelta2Vsync() {
+        if (mRefreshPeriod < 0) {
+            log("Run command \"" + FRAME_LATENCY_CMD + " \" for number of jankiness.");
+            return null;
+        }
+        if (mNormalizedDelta2Vsync[0] < 0) {
+            getNormalizedDelta2Vsync();
+        }
+
+        for (int i = 0; i < mFrameLatencySampleSize - 2; i++) {
+             int value = (int)Math.round(Math.max(mNormalizedDelta2Vsync[i], 0.0));
+             mRoundNormalizedDelta2Vsync[i] = value;
+        }
+        return mRoundNormalizedDelta2Vsync;
+    }
+
+    /*
+     * Get number of jankiness using Vsync time difference
+     */
+    public static int getVsyncJankiness() {
+        if (mRefreshPeriod < 0) {
+            log("Run command \"" + FRAME_LATENCY_CMD + " \" for number of jankiness.");
+            return -1;
+        }
+        if (mRoundNormalizedDelta2Vsync[0] < 0) {
+            getRoundNormalizedDelta2Vsync();
+        }
+        int numberJankiness = 0;
+        for (int i = 0; i < mFrameLatencySampleSize - 2; i++) {
+            int value = mRoundNormalizedDelta2Vsync[i];
+            // ignore the latency which is too long
+            if (value > 0 && value < PAUSE_LATENCY) {
+                numberJankiness++;
+            }
+        }
+        return numberJankiness;
+    }
+
+    /* Track the maximum delta which shows the accumulating time
+     * before animation starts */
+    public static int getMaxDeltaVsync() {
+        return Math.round((float)mMaxDeltaVsync /mRefreshPeriod);
+    }
+
+    /**
+     * Calculate frame rate
+     * @return
+     */
+    public static double getFrameRate() {
+        if (mRefreshPeriod < 0) {
+            log("Run command \"" + FRAME_LATENCY_CMD + " \" before calcuating average frame rate");
+            return -1.0;
+        }
+        if (mFrameBufferData.get(0) == null) {
+            log("Run command \"" + FRAME_LATENCY_CMD + " \" before retrieving frame buffer data");
+            return -1.0;
+        }
+        long startTime = Long.parseLong(mFrameBufferData.get(0).get(1));
+        long endTime =  Long.parseLong(mFrameBufferData.get(mFrameLatencySampleSize - 1).get(1));
+        long totalDuration = endTime - startTime;
+        return (double)((mFrameLatencySampleSize - 1) * Math.pow(10, 9))/totalDuration;
+    }
+
+    /**
+     * Print raw data and processed results into file <testcasename_[iteration]_processed.txt>
+     * @param fileName
+     * @param index
+     */
+    public static void printData(String fileName, int index) {
+        String rawAndProcDataFileName = String.format("%s/%s_%d_processed.txt", RAW_DATA_DIR,
+                fileName, index);
+        log("write raw data and process data into file: " + rawAndProcDataFileName);
+        BufferedWriter fw = null;
+        try {
+            fw = new BufferedWriter(new FileWriter(new File(rawAndProcDataFileName), false));
+            // Show the number of jankiness first:
+            fw.write(String.format("Jankiness count: %d\n", getVsyncJankiness()));
+            fw.write(String.format("Max accumulated frames: %d\n", getMaxDeltaVsync()));
+            fw.write(String.format("Frame rate is: %f\n", getFrameRate()));
+
+            // refresh period
+            fw.write(String.valueOf(mRefreshPeriod));
+            fw.write("\n");
+            fw.write("app\tvsync\tset\tdelta(vsync)\tdelta^2(vsync)\t" +
+                    "delta^2(vsync)/refreshPeriod\t normalized delta^2(vsync)\n");
+
+            for (int i = 0; i < mFrameLatencySampleSize; i++) {
+                // write raw data
+                List<String> rawData = mFrameBufferData.get(i);
+                String line = String.format("%s\t%s\t%s\t%d\t%d\t%f\t%d\n",
+                        rawData.get(0), rawData.get(1), rawData.get(2),
+                        mDeltaVsync[i], mDelta2Vsync[i],
+                        mNormalizedDelta2Vsync[i], mRoundNormalizedDelta2Vsync[i]);
+                fw.write(line);
+            }
+        } catch (IOException e) {
+            log("Open file error: " + e.toString());
+        } finally {
+            try {
+                if (fw != null) {
+                    fw.flush();
+                    fw.close();
+                }
+            }
+            catch (IOException e) {
+                Log.e(TAG, "close file exception: ", e);
+            }
+        }
+    }
+
+    private static void log(String msg) {
+        Log.v(TAG, msg);
+    }
+}
diff --git a/uiautomator_test_libraries/src/com/android/uiautomator/platform/TestWatchers.java b/uiautomator_test_libraries/src/com/android/uiautomator/platform/TestWatchers.java
new file mode 100644
index 0000000..5cab83a
--- /dev/null
+++ b/uiautomator_test_libraries/src/com/android/uiautomator/platform/TestWatchers.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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.android.uiautomator.platform;
+
+import com.android.uiautomator.common.UiWatchers;
+
+public class TestWatchers extends UiWatchers {
+    private String TAG = "TestWatchers";
+
+    @Override
+    public void onAnrDetected(String errorText) {
+        // The ANR dialog is still open now and upon returning from here
+        // it will automatically get closed. See UiWatchers or implement
+        // your handlers directly.
+        super.onAnrDetected("ANR:" + errorText);
+    }
+
+    @Override
+    public void onCrashDetected(String errorText) {
+        // what do we need to do here?
+        // The Crash dialog is still open now and upon returning from here
+        // it will automatically get closed. See UiWatchers or implement
+        // your handlers directly.
+        super.onCrashDetected("CRASH:" + errorText);
+    }
+}
diff --git a/utils/Android.mk b/utils/Android.mk
new file mode 100644
index 0000000..c141484
--- /dev/null
+++ b/utils/Android.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2012 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.
+#
+
+include $(call all-subdir-makefiles)
diff --git a/utils/DummyIME/Android.mk b/utils/DummyIME/Android.mk
new file mode 100644
index 0000000..c8d9f87
--- /dev/null
+++ b/utils/DummyIME/Android.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2012 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := DummyIME
+
+include $(BUILD_PACKAGE)
diff --git a/utils/DummyIME/AndroidManifest.xml b/utils/DummyIME/AndroidManifest.xml
new file mode 100644
index 0000000..fd17a52
--- /dev/null
+++ b/utils/DummyIME/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<!--
+/*
+ * Copyright 2006, 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.android.testing.dummyime">
+    <application android:label="Dummy IME">
+        <service android:name="DummyIme"
+                android:permission="android.permission.BIND_INPUT_METHOD">
+            <intent-filter>
+                <action android:name="android.view.InputMethod" />
+            </intent-filter>
+            <meta-data android:name="android.view.im" android:resource="@xml/method" />
+        </service>
+        <activity android:name=".ImePreferences" android:label="Dummy IME Settings">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/utils/DummyIME/res/xml/method.xml b/utils/DummyIME/res/xml/method.xml
new file mode 100644
index 0000000..43a330e
--- /dev/null
+++ b/utils/DummyIME/res/xml/method.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2012, 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.
+ */
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- for the Search Manager. -->
+
+<input-method xmlns:android="http://schemas.android.com/apk/res/android"
+        android:settingsActivity="com.android.testing.dummyime.ImePreferences">
+    <subtype
+        android:label="Generic"
+        android:imeSubtypeLocale="en_US"
+        android:imeSubtypeMode="keyboard" />
+</input-method>
\ No newline at end of file
diff --git a/utils/DummyIME/src/com/android/testing/dummyime/DummyIme.java b/utils/DummyIME/src/com/android/testing/dummyime/DummyIme.java
new file mode 100644
index 0000000..7b7a39a
--- /dev/null
+++ b/utils/DummyIME/src/com/android/testing/dummyime/DummyIme.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 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.android.testing.dummyime;
+
+import android.inputmethodservice.InputMethodService;
+
+/**
+ * Dummy IME implementation that basically does nothing
+ */
+public class DummyIme extends InputMethodService {
+
+    @Override
+    public boolean onEvaluateFullscreenMode() {
+        return false;
+    }
+
+    @Override
+    public boolean onEvaluateInputViewShown() {
+        return false;
+    }
+}
diff --git a/utils/DummyIME/src/com/android/testing/dummyime/ImePreferences.java b/utils/DummyIME/src/com/android/testing/dummyime/ImePreferences.java
new file mode 100644
index 0000000..41036ab
--- /dev/null
+++ b/utils/DummyIME/src/com/android/testing/dummyime/ImePreferences.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2012 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.android.testing.dummyime;
+
+import android.preference.PreferenceActivity;
+
+/**
+ * Dummy IME preference activity
+ */
+public class ImePreferences extends PreferenceActivity {
+
+}
