Merge branch 'master' into robo-staging
diff --git a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowApplication.java b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowApplication.java
index 77864d3..8a07a83 100644
--- a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowApplication.java
+++ b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowApplication.java
@@ -2,7 +2,13 @@
 
 import android.app.Application;
 import android.appwidget.AppWidgetManager;
-import android.content.*;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
 import android.content.res.Resources;
 import android.os.IBinder;
 import android.os.Looper;
@@ -16,7 +22,11 @@
 import com.xtremelabs.robolectric.tester.org.apache.http.FakeHttpLayer;
 import com.xtremelabs.robolectric.util.Scheduler;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 import static com.xtremelabs.robolectric.Robolectric.newInstanceOf;
 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
@@ -416,6 +426,25 @@
         }
     }
 
+    public boolean hasReceiverForIntent(Intent intent) {
+        for (Wrapper wrapper : registeredReceivers) {
+            if (wrapper.intentFilter.matchAction(intent.getAction())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public List<BroadcastReceiver> getReceiversForIntent(Intent intent) {
+        ArrayList<BroadcastReceiver> broadcastReceivers = new ArrayList<BroadcastReceiver>();
+        for (Wrapper wrapper : registeredReceivers) {
+            if (wrapper.intentFilter.matchAction(intent.getAction())) {
+                broadcastReceivers.add(wrapper.getBroadcastReceiver());
+            }
+        }
+        return broadcastReceivers;
+    }
+
     /**
      * Non-Android accessor.
      *
diff --git a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowProgressBar.java b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowProgressBar.java
index ef51200..b178301 100644
--- a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowProgressBar.java
+++ b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowProgressBar.java
@@ -1,53 +1,78 @@
 package com.xtremelabs.robolectric.shadows;
 
-import android.widget.ProgressBar;
 import com.xtremelabs.robolectric.internal.Implementation;
 import com.xtremelabs.robolectric.internal.Implements;
 
+import android.widget.ProgressBar;
+
 @Implements(ProgressBar.class)
 public class ShadowProgressBar extends ShadowView {
 
-  private int progress;
-  private int secondaryProgress;
-  private int max = 100;
+    private int progress;
+    private int secondaryProgress;
+    private int max = 100;
+    private boolean isIndeterminate;
 
-  @Override public void applyAttributes() {
-      super.applyAttributes();
-      
-      final int max = attributeSet.getAttributeIntValue("android", "max", this.max);
-      
-      if (max >= 0)
-          setMax(max);
-  }
-  
-  @Implementation
-  public void setMax(int max) {
-    progress = 0;
-    this.max = max;
-  }
+    @Override
+    public void applyAttributes() {
+        super.applyAttributes();
 
-  @Implementation
-  public int getMax() {
-    return max;
-  }
+        final int max = attributeSet.getAttributeIntValue("android", "max", this.max);
 
-  @Implementation
-  public void setProgress(int progress) {
-    this.progress = progress;
-  }
+        if (max >= 0)
+            setMax(max);
+    }
 
-  @Implementation
-  public int getProgress() {
-    return progress;
-  }
-  
-  @Implementation
-  public void setSecondaryProgress(int secondaryProgress) {
-    this.secondaryProgress = secondaryProgress;
-  }
-  
-  @Implementation
-  public int getSecondaryProgress() {
-    return secondaryProgress;
-  }
+    @Implementation
+    public void setMax(int max) {
+        this.max = max;
+        if (progress > max) {
+            progress = max;
+        }
+    }
+
+    @Implementation
+    public int getMax() {
+        return max;
+    }
+
+    @Implementation
+    public void setProgress(int progress) {
+        if (!isIndeterminate()) this.progress = Math.min(max, progress);
+    }
+
+    @Implementation
+    public int getProgress() {
+        return isIndeterminate ? 0 : progress;
+    }
+
+    @Implementation
+    public void setSecondaryProgress(int secondaryProgress) {
+        if (!isIndeterminate()) this.secondaryProgress = Math.min(max, secondaryProgress);
+    }
+
+    @Implementation
+    public int getSecondaryProgress() {
+        return isIndeterminate ? 0 : secondaryProgress;
+    }
+
+    @Implementation
+    public void setIndeterminate(boolean indeterminate) {
+        this.isIndeterminate = indeterminate;
+    }
+
+    @Implementation
+    public boolean isIndeterminate() {
+        return isIndeterminate;
+    }
+
+    @Implementation
+    public void incrementProgressBy(int diff) {
+        if (!isIndeterminate()) setProgress(progress + diff);
+    }
+
+    @Implementation
+    public void incrementSecondaryProgressBy(int diff) {
+        if (!isIndeterminate()) setSecondaryProgress(secondaryProgress + diff);
+    }
 }
diff --git a/src/test/java/com/xtremelabs/robolectric/shadows/ApplicationTest.java b/src/test/java/com/xtremelabs/robolectric/shadows/ApplicationTest.java
index ab3afad..e9b7358 100644
--- a/src/test/java/com/xtremelabs/robolectric/shadows/ApplicationTest.java
+++ b/src/test/java/com/xtremelabs/robolectric/shadows/ApplicationTest.java
@@ -2,6 +2,7 @@
 
 import android.app.Activity;
 import android.app.Application;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.ContextWrapper;
@@ -28,9 +29,12 @@
 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
 import static com.xtremelabs.robolectric.util.TestUtil.newConfig;
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
 import static org.hamcrest.CoreMatchers.sameInstance;
 import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -166,52 +170,52 @@
         assertNull(service.service);
         assertNull(shadowApplication.peekNextStartedService());
     }
-    
-    @Test 
+
+    @Test
     public void shouldHaveStoppedServiceIntentAndIndicateServiceWasntRunning() {
-    	ShadowApplication shadowApplication = Robolectric.shadowOf(Robolectric.application);
-    	
-    	Activity activity = new Activity();
-    	
-    	Intent intent = getSomeActionIntent("some.action");
-    	
-    	boolean wasRunning = activity.stopService(intent);
-    	
-    	assertFalse(wasRunning);
-    	assertEquals(intent, shadowApplication.getNextStoppedService());
+        ShadowApplication shadowApplication = Robolectric.shadowOf(Robolectric.application);
+
+        Activity activity = new Activity();
+
+        Intent intent = getSomeActionIntent("some.action");
+
+        boolean wasRunning = activity.stopService(intent);
+
+        assertFalse(wasRunning);
+        assertEquals(intent, shadowApplication.getNextStoppedService());
     }
-    
+
     private Intent getSomeActionIntent(String action) {
-    	Intent intent = new Intent();
-    	intent.setAction(action);
-    	return intent;
+        Intent intent = new Intent();
+        intent.setAction(action);
+        return intent;
     }
-    
+
     @Test
     public void shouldHaveStoppedServiceIntentAndIndicateServiceWasRunning() {
-    	ShadowApplication shadowApplication = shadowOf(Robolectric.application);
-    	
-    	Activity activity = new Activity();
-    	
-    	Intent intent = getSomeActionIntent("some.action");
-    	
-    	activity.startService(intent);
-    	
-    	boolean wasRunning = activity.stopService(intent);
-    	
-    	assertTrue(wasRunning);
-    	assertEquals(intent, shadowApplication.getNextStoppedService());
+        ShadowApplication shadowApplication = shadowOf(Robolectric.application);
+
+        Activity activity = new Activity();
+
+        Intent intent = getSomeActionIntent("some.action");
+
+        activity.startService(intent);
+
+        boolean wasRunning = activity.stopService(intent);
+
+        assertTrue(wasRunning);
+        assertEquals(intent, shadowApplication.getNextStoppedService());
     }
-    
+
     @Test
     public void shouldClearStartedServiceIntents() {
-    	ShadowApplication shadowApplication = shadowOf(Robolectric.application);
-    	shadowApplication.startService(getSomeActionIntent("some.action"));
-    	shadowApplication.startService(getSomeActionIntent("another.action"));
-    	
-    	shadowApplication.clearStartedServices();
-    	
-    	assertNull(shadowApplication.getNextStartedService());
+        ShadowApplication shadowApplication = shadowOf(Robolectric.application);
+        shadowApplication.startService(getSomeActionIntent("some.action"));
+        shadowApplication.startService(getSomeActionIntent("another.action"));
+
+        shadowApplication.clearStartedServices();
+
+        assertNull(shadowApplication.getNextStartedService());
     }
 
     @Test(expected = IllegalStateException.class)
@@ -229,16 +233,37 @@
 
         shadowOf(Robolectric.application).assertNoBroadcastListenersOfActionRegistered(activity, "Bar");
     }
-    
+
     @Test
-	public void broadcasts_shouldBeLogged() {
-		Intent broadcastIntent = new Intent("foo");
-		Robolectric.application.sendBroadcast(broadcastIntent);
-		
-		List<Intent> broadcastIntents = shadowOf(Robolectric.application).getBroadcastIntents();
-		assertTrue(broadcastIntents.size() == 1);
-		assertEquals(broadcastIntent, broadcastIntents.get(0));
-	}
+    public void canAnswerIfReceiverIsRegisteredForIntent() throws Exception {
+        BroadcastReceiver expectedReceiver = new TestBroadcastReceiver();
+        ShadowApplication shadowApplication = shadowOf(Robolectric.application);
+        assertFalse(shadowApplication.hasReceiverForIntent(new Intent("Foo")));
+        Robolectric.application.registerReceiver(expectedReceiver, new IntentFilter("Foo"));
+
+        assertTrue(shadowApplication.hasReceiverForIntent(new Intent("Foo")));
+    }
+
+    @Test
+    public void canFindAllReceiversForAnIntent() throws Exception {
+        BroadcastReceiver expectedReceiver = new TestBroadcastReceiver();
+        ShadowApplication shadowApplication = shadowOf(Robolectric.application);
+        assertFalse(shadowApplication.hasReceiverForIntent(new Intent("Foo")));
+        Robolectric.application.registerReceiver(expectedReceiver, new IntentFilter("Foo"));
+        Robolectric.application.registerReceiver(expectedReceiver, new IntentFilter("Foo"));
+
+        assertTrue(shadowApplication.getReceiversForIntent(new Intent("Foo")).size() == 2);
+    }
+
+    @Test
+    public void broadcasts_shouldBeLogged() {
+        Intent broadcastIntent = new Intent("foo");
+        Robolectric.application.sendBroadcast(broadcastIntent);
+
+        List<Intent> broadcastIntents = shadowOf(Robolectric.application).getBroadcastIntents();
+        assertTrue(broadcastIntents.size() == 1);
+        assertEquals(broadcastIntent, broadcastIntents.get(0));
+    }
 
     private static class NullBinder implements IBinder {
         @Override
@@ -279,8 +304,8 @@
             return false;
         }
 
-		@Override
-		public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
-		}
+        @Override
+        public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
+        }
     }
 }
diff --git a/src/test/java/com/xtremelabs/robolectric/shadows/ProgressBarTest.java b/src/test/java/com/xtremelabs/robolectric/shadows/ProgressBarTest.java
index 8614291..5b419e3 100644
--- a/src/test/java/com/xtremelabs/robolectric/shadows/ProgressBarTest.java
+++ b/src/test/java/com/xtremelabs/robolectric/shadows/ProgressBarTest.java
@@ -7,7 +7,10 @@
 import org.junit.runner.RunWith;
 
 import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 
 @RunWith(WithTestDefaultsRunner.class)
 public class ProgressBarTest {
@@ -24,7 +27,7 @@
     public void shouldInitMaxTo100() {
         assertThat(progressBar.getMax(), equalTo(100));
     }
-    
+
     @Test
     public void testMax() {
         for (int max : testValues) {
@@ -40,7 +43,7 @@
             assertThat(progressBar.getProgress(), equalTo(progress));
         }
     }
-    
+
     @Test
     public void testSecondaryProgress() {
         for (int progress : testValues) {
@@ -48,4 +51,57 @@
             assertThat(progressBar.getSecondaryProgress(), equalTo(progress));
         }
     }
+
+    @Test
+    public void testIsDeterminate() throws Exception {
+        assertFalse(progressBar.isIndeterminate());
+        progressBar.setIndeterminate(true);
+        assertTrue(progressBar.isIndeterminate());
+    }
+
+    @Test
+    public void shouldReturnZeroAsProgressWhenIndeterminate() throws Exception {
+        progressBar.setProgress(10);
+        progressBar.setSecondaryProgress(20);
+        progressBar.setIndeterminate(true);
+        assertEquals(0, progressBar.getProgress());
+        assertEquals(0, progressBar.getSecondaryProgress());
+        progressBar.setIndeterminate(false);
+
+        assertEquals(10, progressBar.getProgress());
+        assertEquals(20, progressBar.getSecondaryProgress());
+    }
+
+    @Test
+    public void shouldNotSetProgressWhenIndeterminate() throws Exception {
+        progressBar.setIndeterminate(true);
+        progressBar.setProgress(10);
+        progressBar.setSecondaryProgress(20);
+        progressBar.setIndeterminate(false);
+
+        assertEquals(0, progressBar.getProgress());
+        assertEquals(0, progressBar.getSecondaryProgress());
+    }
+
+    @Test
+    public void testIncrementProgressBy() throws Exception {
+        assertEquals(0, progressBar.getProgress());
+        progressBar.incrementProgressBy(1);
+        assertEquals(1, progressBar.getProgress());
+        progressBar.incrementProgressBy(1);
+        assertEquals(2, progressBar.getProgress());
+
+        assertEquals(0, progressBar.getSecondaryProgress());
+        progressBar.incrementSecondaryProgressBy(1);
+        assertEquals(1, progressBar.getSecondaryProgress());
+        progressBar.incrementSecondaryProgressBy(1);
+        assertEquals(2, progressBar.getSecondaryProgress());
+    }
+
+    @Test
+    public void shouldRespectMax() throws Exception {
+        progressBar.setMax(20);
+        progressBar.setProgress(50);
+        assertEquals(20, progressBar.getProgress());
+    }
 }