Program: 160289
Project: 160289
Buggy source:
/** 
 * Test case that makes sure STOPPED notification is sent only once with continuous pull replication https://github.com/couchbase/couchbase-lite-android/issues/442
 */
public void testContinuousPullReplicationSendStoppedOnce() throws Exception {
  Log.d(TAG,"String_Node_Str");
  MockDispatcher dispatcher=new MockDispatcher();
  MockWebServer server=MockHelper.getMockWebServer(dispatcher);
  dispatcher.setServerType(MockDispatcher.ServerType.SYNC_GW);
  MockCheckpointPut mockCheckpointPut=new MockCheckpointPut();
  mockCheckpointPut.setSticky(true);
  dispatcher.enqueueResponse(MockHelper.PATH_REGEX_CHECKPOINT,mockCheckpointPut);
  MockChangesFeed mockChangesFeed=new MockChangesFeed();
  dispatcher.enqueueResponse(MockHelper.PATH_REGEX_CHANGES,mockChangesFeed.generateMockResponse());
  server.play();
  Replication pullReplication=database.createPullReplication(server.getUrl("String_Node_Str"));
  pullReplication.setContinuous(true);
  final CountDownLatch enteredIdleState=new CountDownLatch(1);
  final CountDownLatch enteredStoppedState=new CountDownLatch(2);
  pullReplication.addChangeListener(new Replication.ChangeListener(){
    @Override public void changed(    Replication.ChangeEvent event){
      if (event.getSource().getStatus() == Replication.ReplicationStatus.REPLICATION_IDLE) {
        Log.d(TAG,"String_Node_Str");
        enteredIdleState.countDown();
      }
 else       if (event.getSource().getStatus() == Replication.ReplicationStatus.REPLICATION_STOPPED) {
        Log.d(TAG,"String_Node_Str");
        enteredStoppedState.countDown();
      }
    }
  }
);
  pullReplication.start();
  boolean success=enteredIdleState.await(30,TimeUnit.SECONDS);
  assertTrue(success);
  stopReplication(pullReplication);
  Log.d(TAG,"String_Node_Str");
  success=enteredStoppedState.await(Replication.DEFAULT_MAX_TIMEOUT_FOR_SHUTDOWN + 30,TimeUnit.SECONDS);
  assertEquals(1,enteredStoppedState.getCount());
  assertFalse(success);
  Log.d(TAG,"String_Node_Str");
  server.shutdown();
  Log.d(TAG,"String_Node_Str");
}

Fixed version (ground truth):
/** 
 * Test case that makes sure STOPPED notification is sent only once with continuous pull replication https://github.com/couchbase/couchbase-lite-android/issues/442
 */
public void testContinuousPullReplicationSendStoppedOnce() throws Exception {
  Log.d(TAG,"String_Node_Str");
  MockDispatcher dispatcher=new MockDispatcher();
  MockWebServer server=MockHelper.getMockWebServer(dispatcher);
  dispatcher.setServerType(MockDispatcher.ServerType.SYNC_GW);
  MockCheckpointPut mockCheckpointPut=new MockCheckpointPut();
  mockCheckpointPut.setSticky(true);
  dispatcher.enqueueResponse(MockHelper.PATH_REGEX_CHECKPOINT,mockCheckpointPut);
  MockChangesFeed mockChangesFeed=new MockChangesFeed();
  dispatcher.enqueueResponse(MockHelper.PATH_REGEX_CHANGES,mockChangesFeed.generateMockResponse());
  server.play();
  Replication pullReplication=database.createPullReplication(server.getUrl("String_Node_Str"));
  pullReplication.setContinuous(true);
  final CountDownLatch enteredIdleState=new CountDownLatch(1);
  final CountDownLatch enteredStoppedState=new CountDownLatch(2);
  pullReplication.addChangeListener(new Replication.ChangeListener(){
    @Override public void changed(    Replication.ChangeEvent event){
      if (event.getSource().getStatus() == Replication.ReplicationStatus.REPLICATION_IDLE) {
        Log.d(TAG,"String_Node_Str");
        enteredIdleState.countDown();
      }
 else       if (event.getSource().getStatus() == Replication.ReplicationStatus.REPLICATION_STOPPED) {
        Log.d(TAG,"String_Node_Str");
        enteredStoppedState.countDown();
      }
    }
  }
);
  pullReplication.start();
  boolean success=enteredIdleState.await(30,TimeUnit.SECONDS);
  assertTrue(success);
  stopReplication(pullReplication);
  Log.d(TAG,"String_Node_Str");
  success=enteredStoppedState.await(30,TimeUnit.SECONDS);
  assertEquals(1,enteredStoppedState.getCount());
  assertFalse(success);
  Log.d(TAG,"String_Node_Str");
  server.shutdown();
  Log.d(TAG,"String_Node_Str");
}