diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..7d61619
--- /dev/null
+++ b/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, testrunner) \
+    $(call all-java-files-under, core)
+
+uiautomator_internal_api_file := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/uiautomator_api.txt
+
+###############################################
+# Build core library
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(uiautomator.core_src_files)
+LOCAL_MODULE := ub-uiautomator
+LOCAL_SDK_VERSION := current
+
+gen := $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE),,COMMON)/BuildConstants.java
+$(gen) : $(LOCAL_PATH)/BuildConstants.java.in
+	@echo Generating: $@
+	@ mkdir -p $(dir $@)
+	$(hide) sed -e 's/%BUILD_NUMBER%/$(BUILD_NUMBER)/' \
+		$< > $@
+
+LOCAL_GENERATED_SOURCES += $(gen)
+
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+# establish dependency on apicheck
+uiautomator_library := $(LOCAL_BUILT_MODULE)
+###############################################
+
+
+###############################################
+# Generate the stub source files
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(uiautomator.core_src_files)
+LOCAL_SDK_VERSION := current
+LOCAL_MODULE_CLASS := DOCS
+LOCAL_DROIDDOC_HTML_DIR :=
+LOCAL_DROIDDOC_OPTIONS:= \
+    -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_MODULE := ub-uiautomator-docs
+
+include $(BUILD_DROIDDOC)
+
+uiautomator_stubs_stamp := $(full_target)
+$(uiautomator_internal_api_file) : $(full_target)
+
+###############################################
+# API check
+# Please refer to build/core/tasks/apicheck.mk.
+uiautomator_api_dir := frameworks/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_library), \
+    $(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_library), \
+    $(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_library :=
+uiautomator_api_dir :=
+checkapi_last_error_level_flags :=
+checkapi_current_error_level_flags :=
diff --git a/BuildConstants.java.in b/BuildConstants.java.in
new file mode 100644
index 0000000..ce155e8
--- /dev/null
+++ b/BuildConstants.java.in
@@ -0,0 +1,7 @@
+/* This file is auto generated. Do not modify. */
+package com.android.uiautomator.core;
+
+public class BuildConstants {
+    public static final String VERSION_MAIN = "0";
+    public static final String BUILD_NUMBER = "%BUILD_NUMBER%";
+}
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/0.txt b/api/0.txt
new file mode 100644
index 0000000..aabf23f
--- /dev/null
+++ b/api/0.txt
@@ -0,0 +1,226 @@
+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 UiAutomatorInstrumentationTestRunner extends android.test.InstrumentationTestRunner {
+    ctor public UiAutomatorInstrumentationTestRunner();
+  }
+
+  public class UiAutomatorTestCase extends android.test.InstrumentationTestCase {
+    ctor public UiAutomatorTestCase();
+    method public deprecated 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..aabf23f
--- /dev/null
+++ b/api/current.txt
@@ -0,0 +1,226 @@
+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 UiAutomatorInstrumentationTestRunner extends android.test.InstrumentationTestRunner {
+    ctor public UiAutomatorInstrumentationTestRunner();
+  }
+
+  public class UiAutomatorTestCase extends android.test.InstrumentationTestCase {
+    ctor public UiAutomatorTestCase();
+    method public deprecated 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/apicheck_msg_current.txt b/apicheck_msg_current.txt
new file mode 100644
index 0000000..989248d
--- /dev/null
+++ b/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/apicheck_msg_last.txt b/apicheck_msg_last.txt
new file mode 100644
index 0000000..2993157
--- /dev/null
+++ b/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/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/core/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java b/core/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
new file mode 100644
index 0000000..1884e06
--- /dev/null
+++ b/core/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
@@ -0,0 +1,228 @@
+/*
+ * 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 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/core/com/android/uiautomator/core/AccessibilityNodeInfoHelper.java b/core/com/android/uiautomator/core/AccessibilityNodeInfoHelper.java
new file mode 100644
index 0000000..54835e3
--- /dev/null
+++ b/core/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/core/com/android/uiautomator/core/Configurator.java b/core/com/android/uiautomator/core/Configurator.java
new file mode 100644
index 0000000..249f404
--- /dev/null
+++ b/core/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/core/com/android/uiautomator/core/InteractionController.java b/core/com/android/uiautomator/core/InteractionController.java
new file mode 100644
index 0000000..73e46f1
--- /dev/null
+++ b/core/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/core/com/android/uiautomator/core/QueryController.java b/core/com/android/uiautomator/core/QueryController.java
new file mode 100644
index 0000000..6931528
--- /dev/null
+++ b/core/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/core/com/android/uiautomator/core/Tracer.java b/core/com/android/uiautomator/core/Tracer.java
new file mode 100644
index 0000000..d574fc0
--- /dev/null
+++ b/core/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/core/com/android/uiautomator/core/UiAutomatorBridge.java b/core/com/android/uiautomator/core/UiAutomatorBridge.java
new file mode 100644
index 0000000..bc5bc8e
--- /dev/null
+++ b/core/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/core/com/android/uiautomator/core/UiCollection.java b/core/com/android/uiautomator/core/UiCollection.java
new file mode 100644
index 0000000..e15beb2
--- /dev/null
+++ b/core/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/core/com/android/uiautomator/core/UiDevice.java b/core/com/android/uiautomator/core/UiDevice.java
new file mode 100644
index 0000000..2a51109
--- /dev/null
+++ b/core/com/android/uiautomator/core/UiDevice.java
@@ -0,0 +1,856 @@
+/*
+ * 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 InstrumentationUiAutomatorBridge mUiAutomationBridge;
+
+    // reference to self
+    private static UiDevice sDevice;
+
+    private UiDevice() {
+        /* hide constructor */
+    }
+
+    /**
+     * @hide
+     */
+    public void initialize(InstrumentationUiAutomatorBridge uiAutomatorBridge) {
+        mUiAutomationBridge = uiAutomatorBridge;
+    }
+
+    boolean isInWatcherContext() {
+        return mInWatcherContext;
+    }
+
+    /**
+     * Provides access the {@link QueryController} and {@link InteractionController}
+     * @return {@link ShellUiAutomatorBridge}
+     */
+    InstrumentationUiAutomatorBridge 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.
+     * Relative file paths are stored the application's internal private storage location.
+     *
+     * @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);
+            File dumpFile = new File(fileName);
+            if (!dumpFile.isAbsolute()) {
+                dumpFile = getAutomatorBridge().getContext().getFileStreamPath(fileName);
+            }
+            AccessibilityNodeInfoDumper.dumpWindowToFile(root, dumpFile, display.getRotation(),
+                    size.x, size.y);
+            Log.d(LOG_TAG, String.format("Saved window hierarchy to %s",
+                    dumpFile.getAbsolutePath()));
+        }
+    }
+
+    /**
+     * 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/core/com/android/uiautomator/core/UiObject.java b/core/com/android/uiautomator/core/UiObject.java
new file mode 100644
index 0000000..4bb99cd
--- /dev/null
+++ b/core/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/core/com/android/uiautomator/core/UiObjectNotFoundException.java b/core/com/android/uiautomator/core/UiObjectNotFoundException.java
new file mode 100644
index 0000000..fc0891b
--- /dev/null
+++ b/core/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/core/com/android/uiautomator/core/UiScrollable.java b/core/com/android/uiautomator/core/UiScrollable.java
new file mode 100644
index 0000000..a8d20c3
--- /dev/null
+++ b/core/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/core/com/android/uiautomator/core/UiSelector.java b/core/com/android/uiautomator/core/UiSelector.java
new file mode 100644
index 0000000..bd61bfd
--- /dev/null
+++ b/core/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/core/com/android/uiautomator/core/UiWatcher.java b/core/com/android/uiautomator/core/UiWatcher.java
new file mode 100644
index 0000000..5403e30
--- /dev/null
+++ b/core/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/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/testrunner/com/android/uiautomator/core/InstrumentationUiAutomatorBridge.java b/testrunner/com/android/uiautomator/core/InstrumentationUiAutomatorBridge.java
new file mode 100644
index 0000000..34e6d23
--- /dev/null
+++ b/testrunner/com/android/uiautomator/core/InstrumentationUiAutomatorBridge.java
@@ -0,0 +1,64 @@
+/*
+ * 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();
+    }
+
+    Context getContext() {
+        return mContext;
+    }
+}
diff --git a/testrunner/com/android/uiautomator/testrunner/IAutomationSupport.java b/testrunner/com/android/uiautomator/testrunner/IAutomationSupport.java
new file mode 100644
index 0000000..f0c60d2
--- /dev/null
+++ b/testrunner/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/testrunner/com/android/uiautomator/testrunner/InstrumentationAutomationSupport.java b/testrunner/com/android/uiautomator/testrunner/InstrumentationAutomationSupport.java
new file mode 100644
index 0000000..a70586e
--- /dev/null
+++ b/testrunner/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/testrunner/com/android/uiautomator/testrunner/UiAutomatorInstrumentationTestRunner.java b/testrunner/com/android/uiautomator/testrunner/UiAutomatorInstrumentationTestRunner.java
new file mode 100644
index 0000000..ae763f2
--- /dev/null
+++ b/testrunner/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/testrunner/com/android/uiautomator/testrunner/UiAutomatorTestCase.java b/testrunner/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
new file mode 100644
index 0000000..b5f21c9
--- /dev/null
+++ b/testrunner/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/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 {
+
+}
