/// <summary>
        /// Subscribes this object to the given database's <c>Changed</c> event for
        /// processing
        /// </summary>
        /// <param name="db">Db.</param>
        public void SubscribeToDatabase(Database db, long since, ChangesOptions options)
        {
            if (db == null)
            {
                return;
            }


            Db       = db;
            IsAsync  = true;
            _since   = since;
            _options = options;
            if (ChangesFeedMode == ChangesFeedMode.LongPoll)
            {
                var currentChanges = Db.ChangesSince(since, options, ChangesFilter, FilterParams);
                IsAsync = !currentChanges.Any();
                if (!IsAsync)
                {
                    if (ChangesIncludeConflicts)
                    {
                        Response.JsonBody = new Body(DatabaseMethods.ResponseBodyForChanges(currentChanges, since, options.Limit, this));
                    }
                    else
                    {
                        Response.JsonBody = new Body(DatabaseMethods.ResponseBodyForChanges(currentChanges, since, this));
                    }
                }
                else
                {
                    Db.Changed += DatabaseChanged;
                }
            }
        }
        // Processes a change in the subscribed database
        private void DatabaseChanged(object sender, DatabaseChangeEventArgs args)
        {
            foreach (var change in args.Changes)
            {
                var rev        = change.AddedRevision;
                var winningRev = change.WinningRevision;

                if (!ChangesIncludeConflicts)
                {
                    if (winningRev == null)
                    {
                        continue; // this change doesn't affect the winning rev ID, no need to send it
                    }

                    if (rev.Equals(winningRev))
                    {
                        // This rev made a _different_ rev current, so substitute that one.
                        // We need to emit the current sequence # in the feed, so put it in the rev.
                        // This isn't correct internally (this is an old rev so it has an older sequence)
                        // but consumers of the _changes feed don't care about the internal state.
                        if (ChangesIncludeDocs)
                        {
                            _db.LoadRevisionBody(rev, DocumentContentOptions.None);
                        }
                    }
                }

                if (!_db.RunFilter(ChangesFilter, null, rev))
                {
                    continue;
                }

                if (ChangesFeedMode == ChangesFeedMode.LongPoll)
                {
                    _changes.Add(rev);
                }
                else
                {
                    Log.D(TAG, "Sending continuous change chunk");
                    var written = Response.SendContinuousLine(DatabaseMethods.ChangesDictForRev(rev, this), ChangesFeedMode);
                    if (!written)
                    {
                        Terminate();
                    }
                }
            }

            if (ChangesFeedMode == ChangesFeedMode.LongPoll && _changes.Count > 0)
            {
                var body = new Body(DatabaseMethods.ResponseBodyForChanges(_changes, 0, this));
                Response.WriteData(body.AsJson(), true);
                CouchbaseLiteRouter.ResponseFinished(this);
            }
        }
 private void WriteChanges(RevisionList changes)
 {
     if (changes.Count > 0)
     {
         if (ChangesFeedMode == ChangesFeedMode.LongPoll)
         {
             var body = new Body(DatabaseMethods.ResponseBodyForChanges(changes, 0, this));
             Response.WriteData(body.AsJson(), true);
             Terminate();
         }
         else
         {
             foreach (var rev in changes)
             {
                 var written = Response.SendContinuousLine(DatabaseMethods.ChangesDictForRev(rev, this), ChangesFeedMode);
                 if (!written)
                 {
                     Terminate();
                     break;
                 }
             }
         }
     }
 }