public void TestPusherDeletedDoc()
        {
            if (!Boolean.Parse((string)GetProperty("replicationTestsEnabled")))
            {
                Assert.Inconclusive("Replication tests disabled.");
                return;
            }

            using (var remoteDb = _sg.CreateDatabase(TempDbName())) {
                var remote = remoteDb.RemoteUri;
                var docIdTimestamp = Convert.ToString((ulong)DateTime.UtcNow.TimeSinceEpoch().TotalMilliseconds);

                // Create some documentsConvert
                var documentProperties = new Dictionary<string, object>();
                var doc1Id = string.Format("doc1-{0}", docIdTimestamp);
                documentProperties["_id"] = doc1Id;
                documentProperties["foo"] = 1;
                documentProperties["bar"] = false;

                var body = new Body(documentProperties);
                var rev1 = new RevisionInternal(body);
                rev1 = database.PutRevision(rev1, null, false);

                documentProperties.SetRevID(rev1.RevID);
                documentProperties["UPDATED"] = true;
                documentProperties["_deleted"] = true;
                database.PutRevision(new RevisionInternal(documentProperties), rev1.RevID, false);

                var repl = database.CreatePushReplication(remote);
                if (!IsSyncGateway(remote)) {
                    ((Pusher)repl).CreateTarget = true;
                }

                RunReplication(repl);

                Assert.IsNull(repl.LastError);

                // make sure doc1 is deleted
                var replicationUrlTrailing = new Uri(string.Format("{0}/", remote));
                var pathToDoc = new Uri(replicationUrlTrailing, doc1Id);
                WriteDebug("Send http request to " + pathToDoc);
                var httpRequestDoneSignal = new CountdownEvent(1);
                using (var httpclient = new HttpClient()) {
                    try {
                        var getDocResponse = httpclient.GetAsync(pathToDoc.ToString()).Result;
                        var statusLine = getDocResponse.StatusCode;
                        WriteDebug("statusLine " + statusLine);
                        Assert.AreEqual(Couchbase.Lite.StatusCode.NotFound, statusLine.GetStatusCode());                        
                    }
                    catch (ProtocolViolationException e) {
                        Assert.IsNull(e, "Got ClientProtocolException: " + e.Message);
                    }
                    catch (IOException e) {
                        Assert.IsNull(e, "Got IOException: " + e.Message);
                    }
                    finally {
                        httpRequestDoneSignal.Signal();
                    }
                    WriteDebug("Waiting for http request to finish");
                    try {
                        httpRequestDoneSignal.Wait(TimeSpan.FromSeconds(10));
                        WriteDebug("http request finished");
                    }
                    catch (Exception e) {
                        Console.WriteLine("Exception during TestPusherDeletedDoc", e);
                    }
                }
            }
        }
        public void TestPusher()
        {
            if (!Boolean.Parse((string)GetProperty("replicationTestsEnabled")))
            {
                Assert.Inconclusive("Replication tests disabled.");
                return;
            }

            using (var remoteDb = _sg.CreateDatabase(TempDbName())) {
                var remote = remoteDb.RemoteUri;
                var docIdTimestamp = Convert.ToString((ulong)DateTime.UtcNow.TimeSinceEpoch().TotalMilliseconds);

                // Create some documents:
                var documentProperties = new Dictionary<string, object>();
                var doc1Id = string.Format("doc1-{0}", docIdTimestamp);
                documentProperties["_id"] = doc1Id;
                documentProperties["foo"] = 1;
                documentProperties["bar"] = false;

                var body = new Body(documentProperties);
                var rev1 = new RevisionInternal(body);
                rev1 = database.PutRevision(rev1, null, false);

                documentProperties.SetRevID(rev1.RevID);
                documentProperties["UPDATED"] = true;
                database.PutRevision(new RevisionInternal(documentProperties), rev1.RevID, false);

                documentProperties = new Dictionary<string, object>();
                var doc2Id = string.Format("doc2-{0}", docIdTimestamp);
                documentProperties["_id"] = doc2Id;
                documentProperties["baz"] = 666;
                documentProperties["fnord"] = true;

                database.PutRevision(new RevisionInternal(documentProperties), null, false);

                var doc2 = database.GetDocument(doc2Id);
                var doc2UnsavedRev = doc2.CreateRevision();
                var attachmentStream = GetAsset("attachment.png");
                doc2UnsavedRev.SetAttachment("attachment_testPusher.png", "image/png", attachmentStream);
                var doc2Rev = doc2UnsavedRev.Save();
                doc2UnsavedRev.Dispose();
                attachmentStream.Dispose();

                Assert.IsNotNull(doc2Rev);

                const bool continuous = false;
                var repl = database.CreatePushReplication(remote);
                repl.Continuous = continuous;
                if (!IsSyncGateway(remote)) {
                    repl.CreateTarget = true;
                }

                // Check the replication's properties:
                Assert.AreEqual(database, repl.LocalDatabase);
                Assert.AreEqual(remote, repl.RemoteUrl);
                Assert.IsFalse(repl.IsPull);
                Assert.IsFalse(repl.Continuous);
                Assert.IsNull(repl.Filter);
                Assert.IsNull(repl.FilterParams);
                Assert.IsNull(repl.DocIds);
                // TODO: CAssertNil(r1.headers); still not null!
                // Check that the replication hasn't started running:
                Assert.IsFalse(repl.IsRunning);
                Assert.AreEqual(ReplicationStatus.Stopped, repl.Status);
                Assert.AreEqual(0, repl.CompletedChangesCount);
                Assert.AreEqual(0, repl.ChangesCount);
                Assert.IsNull(repl.LastError);

                RunReplication(repl);

                // TODO: Verify the foloowing 2 asserts. ChangesCount and CompletedChangesCount
                // should already be reset when the replicator stopped.
                Assert.IsNull(repl.LastError);
                Assert.IsTrue(repl.ChangesCount >= 2);
                Assert.IsTrue(repl.CompletedChangesCount >= 2);


                remoteDb.VerifyDocumentExists(doc1Id);

                // Add doc3
                documentProperties = new Dictionary<string, object>();
                var doc3Id = string.Format("doc3-{0}", docIdTimestamp);
                var doc3 = database.GetDocument(doc3Id);
                documentProperties["bat"] = 677;
                doc3.PutProperties(documentProperties);

                // re-run push replication
                var repl2 = database.CreatePushReplication(remote);
                repl2.Continuous = continuous;
                if (!IsSyncGateway(remote)) {
                    repl2.CreateTarget = true;
                }

                var repl2CheckedpointId = repl2.RemoteCheckpointDocID();

                RunReplication(repl2);

                Assert.IsNull(repl2.LastError);

                Sleep(1000);

                // make sure trhe doc has been added
                remoteDb.VerifyDocumentExists(doc3Id);

                Assert.AreEqual(repl2.LastSequence, database.LastSequenceWithCheckpointId(repl2CheckedpointId));

                Sleep(2000);
                var json = GetRemoteDoc(remote, repl2CheckedpointId);
                var remoteLastSequence = (string)json["lastSequence"];
                Assert.AreEqual(repl2.LastSequence, remoteLastSequence);
            }
        }