protected override IStreamQueryDistributor CreateDistributor(
     Func<Lease, Task> onReceive = null,
     LeasableResource[] leasableResources = null,
     int maxDegreesOfParallelism = 5,
     string name = null,
     TimeSpan? waitInterval = null,
     string scope = null)
 {
     distributor = new InMemoryStreamQueryDistributor(
         leasableResources ?? DefaultLeasableResources,
         scope ?? DateTimeOffset.UtcNow.Ticks.ToString(),
         maxDegreesOfParallelism,
         waitInterval);
     if (onReceive != null)
     {
         distributor.OnReceive(onReceive);
     }
     return distributor;
 }
        public async Task Competing_catchups_can_lease_a_partition_using_a_distributor()
        {
            var partitions = Enumerable.Range(0, 9)
                                       .Select(i => StreamQuery.Partition(i*100, (i + 1)*100))
                                       .ToArray();

            var store = new InMemoryProjectionStore<Projection<HashSet<int>, int>>();

            var aggregator = Aggregator.CreateFor<HashSet<int>, int>((p, xs) =>
            {
                if (p.Value == null)
                {
                    p.Value = new HashSet<int>();
                }

                foreach (var x in xs)
                {
                    p.Value.Add(x);
                }
            }).Trace();

            // set up 10 competing catchups
            for (var i = 0; i < 10; i++)
            {
                var distributor = new InMemoryStreamQueryDistributor(
                    partitions.Select(p => new LeasableResource(p.ToString(), TimeSpan.FromSeconds(10))).ToArray(), "")
                    .Trace();

                distributor.OnReceive(async lease =>
                {
                    var partition = partitions.Single(p => p.ToString() == lease.LeasableResource.Name);
                    var catchup = StreamCatchup.Create(await partitioner.GetStream(partition));
                    catchup.Subscribe(aggregator, store.Trace());
                    await catchup.RunSingleBatch();
                });

                distributor.Start();

                disposables.Add(distributor);
            }

            partitions.ToList()
                      .ForEach(partition =>
                                   store.Should()
                                        .ContainSingle(p =>
                                                           p.Value.Count() == 100 &&
                                                           p.Value.OrderBy(i => i).Last() == partition.UpperBoundInclusive));
        }