ayende/ravendb — pull request #961 by redknightlois (2014-05-22 17:36:14+00:00)
Title: Unification of the RavenDB and RavenFS Changes client.

Even though all tests are green (including those that I could run from RavenDB) this is a PR that requires a review.

Rationale:
The Changes API for RavenFS was built independently of RavenDB therefore most of the issues fixed (corner cases) werent present in the simple RavenFS implementation. Having 2 codepath to access the same endpoint didn't make much sense either. Notifications werent standarized.
After we release we will not be able to change the API surface until RavenDB 4. So it was now or never :)

The scope of the changes are the following:
- Both RavenDB and RavenFS Changes API now use the same underlying mechanism to handle connections (they share the code through the RemoteChangesClientBase abstract class).
- 2 interfaces were introduced to handle the commonalities in the code (IChangesConnectionState and IConnectableChanges --- not sure about the naming for that one)
- The implementation on the RavenFS client now mimic the .Changes() signature found on RavenDB IDocumentStore. (while such constructs do not exist yet for RavenFS -- should they? -- at least to the outsider eye they look very similar)
- Many of the notifications names changed. Still have a couple of things to check with either you or Arek because there are changes in the notifications themselves that make sense but are mostly cosmetics.
- I introduced a few tricks using auto-reference type parameters in the interface to deal with some cosmetic issues in the RemoteChangesClientBase which forced me to do a test in the constructor to ensure that the implementer is implementing the derived class properly (I have added some tests for that in the Raven.Tests.Core\Notifications)

Examples of how the client code looks like now (taken from the tests):
```C#
var task1 = client.Changes().ForFolder("/")
.Timeout(TimeSpan.FromSeconds(2))
.Take(1).ToTask();

var task2 = destination.Changes().ForSynchronization()
.Where(s => s.SynchronizationDirection == SynchronizationDirection.Incoming)
.Timeout(TimeSpan.FromSeconds(20))
.Take(1).ToArray()
.ToTask();
```

There are many cosmetics changes that can be done (and I would like you and Arek to priorize those), but the implementation seemed ready for review as it is.