Merge branch 'master' of github.com:pivotal/robolectric
diff --git a/build.xml b/build.xml
index c5e31aa..ef8e4f9 100644
--- a/build.xml
+++ b/build.xml
@@ -52,10 +52,10 @@
     </path>
 
     <path id="android.target.classpath">
-        <pathelement path="${sdk.dir}/platforms/android-10/android.jar"/>
-        <pathelement path="${sdk.dir}/add-ons/addon_google_apis_google_inc_10/libs/maps.jar"/>
-        <pathelement path="${sdk.dir}/add-ons/addon-google_apis-google_inc_-10/libs/maps.jar"/>
-        <pathelement path="${sdk.dir}/add-ons/addon-google_apis-google-10/libs/maps.jar"/>
+        <pathelement path="${sdk.dir}/platforms/android-14/android.jar"/>
+        <pathelement path="${sdk.dir}/add-ons/addon_google_apis_google_inc_14/libs/maps.jar"/>
+        <pathelement path="${sdk.dir}/add-ons/addon-google_apis-google_inc_-14/libs/maps.jar"/>
+        <pathelement path="${sdk.dir}/add-ons/addon-google_apis-google-14/libs/maps.jar"/>
         <pathelement path="${sdk.dir}/extras/android/support/v4/android-support-v4.jar"/>
         <pathelement path="${sdk.dir}/android-compatibility/v4/android-support-v4.jar"/>
     </path>
diff --git a/pom.xml b/pom.xml
index 573dad0..091af33 100644
--- a/pom.xml
+++ b/pom.xml
@@ -77,7 +77,7 @@
         <dependency>
             <groupId>com.google.android</groupId>
             <artifactId>android</artifactId>
-            <version>2.3.3</version>
+            <version>4.0.1.2</version>
             <scope>provided</scope>
         </dependency>
 
diff --git a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowActivity.java b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowActivity.java
index 086b324..50e40d5 100644
--- a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowActivity.java
+++ b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowActivity.java
@@ -467,6 +467,7 @@
         invoker.call("onResume").withNothing();
     }
 
+    @Implementation
     public void recreate() {
         Bundle outState = new Bundle();
         final ActivityInvoker invoker = new ActivityInvoker();
diff --git a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowAlertDialog.java b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowAlertDialog.java
index 7da34a5..53f20f6 100644
--- a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowAlertDialog.java
+++ b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowAlertDialog.java
@@ -462,7 +462,8 @@
             return dialog;
         }
 
-        protected Context getContext() {
+        @Implementation
+        public Context getContext() {
             return context;
         }
     }
diff --git a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowApplication.java b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowApplication.java
index 99cd2d0..77864d3 100644
--- a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowApplication.java
+++ b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowApplication.java
@@ -30,15 +30,15 @@
     private static final Map<String, String> SYSTEM_SERVICE_MAP = new HashMap<String, String>();
 
     static {
-        // note that this one is different!
+        // note that these are different!
         SYSTEM_SERVICE_MAP.put(Context.WINDOW_SERVICE, "com.xtremelabs.robolectric.tester.android.view.TestWindowManager");
+        SYSTEM_SERVICE_MAP.put(Context.CLIPBOARD_SERVICE, "com.xtremelabs.robolectric.tester.android.text.TestClipboardManager");
 
         // the rest are as mapped in docs...
         SYSTEM_SERVICE_MAP.put(Context.LAYOUT_INFLATER_SERVICE, "android.view.LayoutInflater");
         SYSTEM_SERVICE_MAP.put(Context.ACTIVITY_SERVICE, "android.app.ActivityManager");
         SYSTEM_SERVICE_MAP.put(Context.POWER_SERVICE, "android.os.PowerManager");
         SYSTEM_SERVICE_MAP.put(Context.ALARM_SERVICE, "android.app.AlarmManager");
-        SYSTEM_SERVICE_MAP.put(Context.CLIPBOARD_SERVICE, "android.text.ClipboardManager");
         SYSTEM_SERVICE_MAP.put(Context.NOTIFICATION_SERVICE, "android.app.NotificationManager");
         SYSTEM_SERVICE_MAP.put(Context.KEYGUARD_SERVICE, "android.app.KeyguardManager");
         SYSTEM_SERVICE_MAP.put(Context.LOCATION_SERVICE, "android.location.LocationManager");
diff --git a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowCursorWrapper.java b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowCursorWrapper.java
index 1e6c6b1..9456c6b 100644
--- a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowCursorWrapper.java
+++ b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowCursorWrapper.java
@@ -204,8 +204,14 @@
     public Bundle respond(Bundle bundle) {
         return wrappedCursor.respond(bundle);
     }
+    
+    @Implementation
+	public int getType(int columnIndex) {
+		return 0;
+	}
 
-    public Cursor getWrappedCursor() {
+    @Implementation
+	public Cursor getWrappedCursor() {
         return wrappedCursor;
     }
 
diff --git a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowImageView.java b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowImageView.java
index 7d205da..9963cdf 100644
--- a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowImageView.java
+++ b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowImageView.java
@@ -126,6 +126,7 @@
         return imageDrawable;
     }
 
+    @Implementation
     public int getAlpha() {
         return alpha;
     }
diff --git a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowLooper.java b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowLooper.java
index 5708848..99126e2 100644
--- a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowLooper.java
+++ b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowLooper.java
@@ -19,6 +19,7 @@
 public class ShadowLooper {
     private static ThreadLocal<Looper> looperForThread = makeThreadLocalLoopers();
     private Scheduler scheduler = new Scheduler();
+    private Thread myThread = Thread.currentThread();
 
     boolean quit;
 
@@ -70,6 +71,11 @@
         }
     }
 
+    @Implementation
+    public Thread getThread() {
+    	return myThread;
+    }
+    
     public boolean hasQuit() {
         return quit;
     }
diff --git a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowView.java b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowView.java
index 555be36..baf3ca4 100644
--- a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowView.java
+++ b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowView.java
@@ -643,30 +643,22 @@
         wasInvalidated = false;
     }
 
-    /**
-     * Non-Android accessor.
-     */
+    @Implementation
     public void setLeft(int left) {
         this.left = left;
     }
 
-    /**
-     * Non-Android accessor.
-     */
+    @Implementation
     public void setTop(int top) {
         this.top = top;
     }
 
-    /**
-     * Non-Android accessor.
-     */
+    @Implementation
     public void setRight(int right) {
         this.right = right;
     }
 
-    /**
-     * Non-Android accessor.
-     */
+    @Implementation
     public void setBottom(int bottom) {
         this.bottom = bottom;
     }
diff --git a/src/main/java/com/xtremelabs/robolectric/tester/android/content/TestSharedPreferences.java b/src/main/java/com/xtremelabs/robolectric/tester/android/content/TestSharedPreferences.java
index bb3af56..21f2e3a 100644
--- a/src/main/java/com/xtremelabs/robolectric/tester/android/content/TestSharedPreferences.java
+++ b/src/main/java/com/xtremelabs/robolectric/tester/android/content/TestSharedPreferences.java
@@ -171,5 +171,15 @@
         public void apply() {
             commit();
         }
+
+		@Override
+		public Editor putStringSet(String key, Set<String> values) {
+			return this;
+		}
     }
+
+	@Override
+	public Set<String> getStringSet(String key, Set<String> defValues) {
+		return null;
+	}
 }
diff --git a/src/main/java/com/xtremelabs/robolectric/tester/android/content/pm/StubPackageManager.java b/src/main/java/com/xtremelabs/robolectric/tester/android/content/pm/StubPackageManager.java
index 7e117ef..7f49282 100644
--- a/src/main/java/com/xtremelabs/robolectric/tester/android/content/pm/StubPackageManager.java
+++ b/src/main/java/com/xtremelabs/robolectric/tester/android/content/pm/StubPackageManager.java
@@ -289,4 +289,10 @@
     @Override public boolean isSafeMode() {
         return false;
     }
+
+	@Override public void verifyPendingInstall(int id, int verificationCode) {
+	}
+
+	@Override public void setInstallerPackageName(String targetPackage, String installerPackageName) {
+	}
 }
diff --git a/src/main/java/com/xtremelabs/robolectric/tester/android/database/TestCursor.java b/src/main/java/com/xtremelabs/robolectric/tester/android/database/TestCursor.java
index 72a2d03..84a3d85 100644
--- a/src/main/java/com/xtremelabs/robolectric/tester/android/database/TestCursor.java
+++ b/src/main/java/com/xtremelabs/robolectric/tester/android/database/TestCursor.java
@@ -199,7 +199,12 @@
         throw new UnsupportedOperationException();
     }
 
-    /**
+	@Override
+	public int getType(int columnIndex) {
+        throw new UnsupportedOperationException();
+	}
+
+	/**
      * Mimics ContentResolver.query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
      **/
     public void setQuery(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
diff --git a/src/main/java/com/xtremelabs/robolectric/tester/android/text/TestClipboardManager.java b/src/main/java/com/xtremelabs/robolectric/tester/android/text/TestClipboardManager.java
new file mode 100644
index 0000000..02c8948
--- /dev/null
+++ b/src/main/java/com/xtremelabs/robolectric/tester/android/text/TestClipboardManager.java
@@ -0,0 +1,22 @@
+package com.xtremelabs.robolectric.tester.android.text;
+
+import android.text.ClipboardManager;
+
+@SuppressWarnings("deprecation")
+public class TestClipboardManager extends ClipboardManager {
+
+    private CharSequence text;
+    
+    public void setText(CharSequence text) {
+        this.text = text;
+    }
+
+    public CharSequence getText() {
+        return text;
+    }
+
+    public boolean hasText() {
+        return text != null && text.length() > 0;
+    }
+
+}
diff --git a/src/main/java/com/xtremelabs/robolectric/tester/android/view/TestMenuItem.java b/src/main/java/com/xtremelabs/robolectric/tester/android/view/TestMenuItem.java
index 80cc4d0..4afc9fb 100644
--- a/src/main/java/com/xtremelabs/robolectric/tester/android/view/TestMenuItem.java
+++ b/src/main/java/com/xtremelabs/robolectric/tester/android/view/TestMenuItem.java
@@ -5,9 +5,7 @@
 import android.app.Application;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
-import android.view.ContextMenu;
-import android.view.MenuItem;
-import android.view.SubMenu;
+import android.view.*;
 
 public class TestMenuItem implements MenuItem {
 
@@ -198,4 +196,58 @@
             Robolectric.application.startActivity(intent);
         }
     }
+
+	@Override
+	public void setShowAsAction(int actionEnum) {
+	}
+
+	@Override
+	public MenuItem setShowAsActionFlags(int actionEnum) {
+		return null;
+	}
+
+	@Override
+	public MenuItem setActionView(View view) {
+		return null;
+	}
+
+	@Override
+	public MenuItem setActionView(int resId) {
+		return null;
+	}
+
+	@Override
+	public View getActionView() {
+		return null;
+	}
+
+	@Override
+	public MenuItem setActionProvider(ActionProvider actionProvider) {
+		return null;
+	}
+
+	@Override
+	public ActionProvider getActionProvider() {
+		return null;
+	}
+
+	@Override
+	public boolean expandActionView() {
+		return false;
+	}
+
+	@Override
+	public boolean collapseActionView() {
+		return false;
+	}
+
+	@Override
+	public boolean isActionViewExpanded() {
+		return false;
+	}
+
+	@Override
+	public MenuItem setOnActionExpandListener(OnActionExpandListener listener) {
+		return null;
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/com/xtremelabs/robolectric/tester/android/view/TestWindow.java b/src/main/java/com/xtremelabs/robolectric/tester/android/view/TestWindow.java
index 5976887..d222fe7 100644
--- a/src/main/java/com/xtremelabs/robolectric/tester/android/view/TestWindow.java
+++ b/src/main/java/com/xtremelabs/robolectric/tester/android/view/TestWindow.java
@@ -183,4 +183,15 @@
     @Override public void setSoftInputMode(int softInputMode) {
         this.softInputMode = softInputMode;
     }
+
+	@Override public void invalidatePanelMenu(int featureId) {
+	}
+
+	@Override public boolean superDispatchKeyShortcutEvent(KeyEvent event) {
+		return false;
+	}
+
+	@Override public boolean superDispatchGenericMotionEvent(MotionEvent event) {
+		return false;
+	}
 }
diff --git a/src/test/java/com/xtremelabs/robolectric/shadows/ApplicationTest.java b/src/test/java/com/xtremelabs/robolectric/shadows/ApplicationTest.java
index 8bede6b..ab3afad 100644
--- a/src/test/java/com/xtremelabs/robolectric/shadows/ApplicationTest.java
+++ b/src/test/java/com/xtremelabs/robolectric/shadows/ApplicationTest.java
@@ -278,5 +278,9 @@
         public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
             return false;
         }
+
+		@Override
+		public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
+		}
     }
 }
diff --git a/src/test/java/com/xtremelabs/robolectric/shadows/HandlerThreadTest.java b/src/test/java/com/xtremelabs/robolectric/shadows/HandlerThreadTest.java
index da214a2..8e2340d 100644
--- a/src/test/java/com/xtremelabs/robolectric/shadows/HandlerThreadTest.java
+++ b/src/test/java/com/xtremelabs/robolectric/shadows/HandlerThreadTest.java
@@ -5,6 +5,8 @@
 
 import com.xtremelabs.robolectric.Robolectric;
 import com.xtremelabs.robolectric.WithTestDefaultsRunner;
+
+import org.junit.After;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -13,10 +15,21 @@
 
 @RunWith(WithTestDefaultsRunner.class)
 public class HandlerThreadTest {
+	
+	private HandlerThread handlerThread;
+	
+	@After
+	public void tearDown() throws Exception {
+		// Try to ensure we've exited the thread at the end of each test
+		if ( handlerThread != null ) {
+			handlerThread.quit();
+			handlerThread.join();
+		}
+	}
 
     @Test
     public void shouldReturnLooper() throws Exception {
-        HandlerThread handlerThread = new HandlerThread("test");
+        handlerThread = new HandlerThread("test");
         handlerThread.start();
         assertNotNull(handlerThread.getLooper());
         assertNotSame(handlerThread.getLooper(), Robolectric.application.getMainLooper());
@@ -24,43 +37,45 @@
 
     @Test
     public void shouldReturnNullIfThreadHasNotBeenStarted() throws Exception {
-        HandlerThread handlerThread = new HandlerThread("test");
+        handlerThread = new HandlerThread("test");
         assertNull(handlerThread.getLooper());
     }
 
     @Test
     public void shouldQuitLooperAndThread() throws Exception {
-        HandlerThread handlerThread = new HandlerThread("test");
+        handlerThread = new HandlerThread("test");
         handlerThread.start();
         assertTrue(handlerThread.isAlive());
         assertTrue(handlerThread.quit());
         handlerThread.join();
         assertFalse(handlerThread.isAlive());
+        handlerThread = null;
     }
 
     @Test
     public void shouldStopThreadIfLooperIsQuit() throws Exception {
-        HandlerThread ht = new HandlerThread("test1");
-        ht.start();
-        Looper looper = ht.getLooper();
+        handlerThread = new HandlerThread("test1");
+        handlerThread.start();
+        Looper looper = handlerThread.getLooper();
         assertFalse(shadowOf(looper).quit);
         looper.quit();
-        ht.join();
-        assertFalse(ht.isAlive());
+        handlerThread.join();
+        assertFalse(handlerThread.isAlive());
         assertTrue(shadowOf(looper).quit);
+        handlerThread = null;
     }
 
     @Test
     public void shouldCallOnLooperPrepared() throws Exception {
         final Boolean[] wasCalled = new Boolean[] { false };
-        HandlerThread t = new HandlerThread("test") {
+        handlerThread = new HandlerThread("test") {
             @Override
             protected void onLooperPrepared() {
                 wasCalled[0] = true;
             }
         };
-        t.start();
-        assertNotNull(t.getLooper());
+        handlerThread.start();
+        assertNotNull(handlerThread.getLooper());
         assertTrue(wasCalled[0]);
     }
 }
diff --git a/src/test/java/com/xtremelabs/robolectric/shadows/LooperTest.java b/src/test/java/com/xtremelabs/robolectric/shadows/LooperTest.java
index 11f510c..b2f0c5e 100644
--- a/src/test/java/com/xtremelabs/robolectric/shadows/LooperTest.java
+++ b/src/test/java/com/xtremelabs/robolectric/shadows/LooperTest.java
@@ -98,4 +98,9 @@
         assertTrue(shadowOf(looper).hasQuit());
         assertFalse(shadowOf(looper).getScheduler().areAnyRunnable());
     }
+    
+    @Test
+    public void testLoopThread() {
+    	assertTrue(shadowOf(Looper.getMainLooper()).getThread() == Thread.currentThread());
+    }
 }
diff --git a/src/test/java/com/xtremelabs/robolectric/shadows/TextViewTest.java b/src/test/java/com/xtremelabs/robolectric/shadows/TextViewTest.java
index ff6e886..6e13c40 100644
--- a/src/test/java/com/xtremelabs/robolectric/shadows/TextViewTest.java
+++ b/src/test/java/com/xtremelabs/robolectric/shadows/TextViewTest.java
@@ -460,5 +460,11 @@
         public boolean canSelectArbitrarily() {
             return false;
         }
+
+		@Override
+		public boolean onGenericMotionEvent(TextView widget, Spannable text,
+				MotionEvent event) {
+			return false;
+		}
     }
 }