/// <summary>https://github.com/couchbase/couchbase-lite-java-core/issues/55</summary>
 /// <exception cref="System.Exception"></exception>
 public virtual void TestContinuousPushReplicationGoesIdle()
 {
     // make sure we are starting empty
     NUnit.Framework.Assert.AreEqual(0, database.GetLastSequenceNumber());
     // add docs
     IDictionary<string, object> properties1 = new Dictionary<string, object>();
     properties1.Put("doc1", "testContinuousPushReplicationGoesIdle");
     Document doc1 = CreateDocWithProperties(properties1);
     // create a mock http client that serves as a mocked out sync gateway
     CustomizableMockHttpClient mockHttpClient = new CustomizableMockHttpClient();
     // replication to do initial sync up - has to be continuous replication so the checkpoint id
     // matches the next continuous replication we're gonna do later.
     manager.SetDefaultHttpClientFactory(MockFactoryFactory(mockHttpClient));
     Replication firstPusher = database.CreatePushReplication(GetReplicationURL());
     firstPusher.SetContinuous(true);
     string checkpointId = firstPusher.RemoteCheckpointDocID();
     // save the checkpoint id for later usage
     // intercept checkpoint PUT request and return a 201 response with expected json
     mockHttpClient.SetResponder("_local", new _Responder_1762(checkpointId));
     // start the continuous replication
     CountDownLatch replicationIdleSignal = new CountDownLatch(1);
     LiteTestCase.ReplicationIdleObserver replicationIdleObserver = new LiteTestCase.ReplicationIdleObserver
         (replicationIdleSignal);
     firstPusher.AddChangeListener(replicationIdleObserver);
     firstPusher.Start();
     // wait until we get an IDLE event
     bool successful = replicationIdleSignal.Await(30, TimeUnit.Seconds);
     NUnit.Framework.Assert.IsTrue(successful);
     StopReplication(firstPusher);
     // the last sequence should be "1" at this point.  we will use this later
     string lastSequence = database.LastSequenceWithCheckpointId(checkpointId);
     NUnit.Framework.Assert.AreEqual("1", lastSequence);
     // start a second continuous replication
     Replication secondPusher = database.CreatePushReplication(GetReplicationURL());
     secondPusher.SetContinuous(true);
     string secondPusherCheckpointId = secondPusher.RemoteCheckpointDocID();
     NUnit.Framework.Assert.AreEqual(checkpointId, secondPusherCheckpointId);
     // when this goes to fetch the checkpoint, return the last sequence from the previous replication
     mockHttpClient.SetResponder("_local", new _Responder_1793(secondPusherCheckpointId
         , lastSequence));
     // start second replication
     replicationIdleSignal = new CountDownLatch(1);
     replicationIdleObserver = new LiteTestCase.ReplicationIdleObserver(replicationIdleSignal
         );
     secondPusher.AddChangeListener(replicationIdleObserver);
     secondPusher.Start();
     // wait until we get an IDLE event
     successful = replicationIdleSignal.Await(30, TimeUnit.Seconds);
     NUnit.Framework.Assert.IsTrue(successful);
     StopReplication(secondPusher);
 }
 /// <summary>Test for the private goOffline() method, which still in "incubation".</summary>
 /// <remarks>
 /// Test for the private goOffline() method, which still in "incubation".
 /// This test is brittle because it depends on the following observed behavior,
 /// which will probably change:
 /// - the replication will go into an "idle" state after starting the change listener
 /// Which does not match: https://github.com/couchbase/couchbase-lite-android/wiki/Replicator-State-Descriptions
 /// The reason we need to wait for it to go into the "idle" state, is otherwise the following sequence happens:
 /// 1) Call replicator.start()
 /// 2) Call replicator.goOffline()
 /// 3) Does not cancel changetracker, because changetracker is still null
 /// 4) After getting the remote sequence from http://sg/_local/.., it starts the ChangeTracker
 /// 5) Now the changetracker is running even though we've told it to go offline.
 /// </remarks>
 /// <exception cref="System.Exception"></exception>
 public virtual void TestGoOffline()
 {
     Uri remote = GetReplicationURL();
     Replication replicator = database.CreatePullReplication(remote);
     replicator.SetContinuous(true);
     // add replication "idle" observer - exploit the fact that during observation,
     // the replication will go into an "idle" state after starting the change listener.
     CountDownLatch countDownLatch = new CountDownLatch(1);
     LiteTestCase.ReplicationIdleObserver replicationObserver = new LiteTestCase.ReplicationIdleObserver
         (countDownLatch);
     replicator.AddChangeListener(replicationObserver);
     // add replication observer
     CountDownLatch countDownLatch2 = new CountDownLatch(1);
     LiteTestCase.ReplicationFinishedObserver replicationFinishedObserver = new LiteTestCase.ReplicationFinishedObserver
         (countDownLatch2);
     replicator.AddChangeListener(replicationFinishedObserver);
     replicator.Start();
     bool success = countDownLatch.Await(30, TimeUnit.Seconds);
     NUnit.Framework.Assert.IsTrue(success);
     PutReplicationOffline(replicator);
     NUnit.Framework.Assert.IsTrue(replicator.GetStatus() == Replication.ReplicationStatus
         .ReplicationOffline);
     replicator.Stop();
     bool success2 = countDownLatch2.Await(30, TimeUnit.Seconds);
     NUnit.Framework.Assert.IsTrue(success2);
 }