public Task ClearStateAsync(string grainType, Orleans.GrainReference grainReference, Orleans.GrainState grainState)
        {
            if (!(grainState is IAggregateState))
                throw new NotAggregateStateException(grainState.GetType());

            var state = grainState as IAggregateState;
            var stream = this.GetStreamName(grainType, grainReference);

            return this.Connection.DeleteStreamAsync(stream, state.Version);
        }
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, Orleans.IGrainState grainState)
        {
            if (!(grainState is IAggregateState))
                throw new NotAggregateStateException(grainState.GetType());

            var state = grainState as IAggregateState;
            var stream = this.GetStreamName(grainType, grainReference);

            var newEvents = state.UncommitedEvents;

            if (newEvents.Count == 0)
                return;

            var originalVersion = state.Version - newEvents.Count - 1;
            var expectedVersion = originalVersion == -1 ? ExpectedVersion.NoStream : originalVersion;
            var eventsToSave = newEvents.Select(e => ToEventData(e)).ToList();

            if (eventsToSave.Count < WritePageSize)
            {
                await this.Connection.AppendToStreamAsync(stream, expectedVersion, eventsToSave.ToArray());
            }
            else
            {
                var transaction = await this.Connection.StartTransactionAsync(stream, expectedVersion);

                var position = 0;
                while (position < eventsToSave.Count)
                {
                    var pageEvents = eventsToSave.Skip(position).Take(WritePageSize);
                    await transaction.WriteAsync(pageEvents);
                    position += WritePageSize;
                }

                await transaction.CommitAsync();
            }

            state.UncommitedEvents.Clear();
        }