public DefaultReconciliationOrchestrator(
            IAggregateReconciler aggregateReconciler,
            Func <Reference, EventCentricAggregateRoot> aggregateSource,
            IEventReconciler eventReconciler,
            Func <ulong, TEventSequence> sequenceFactory,
            IStore <TEventSequence, ulong> sequenceStore,
            Func <ISnapshot> snapshotSource)
        {
            this.aggregateReconciler = ArgumentNotNull(
                aggregateReconciler,
                nameof(aggregateReconciler),
                DefaultReconciliationOrchestratorAggregateReconcilerRequired);

            this.aggregateSource = ArgumentNotNull(
                aggregateSource,
                nameof(aggregateSource),
                DefaultReconciliationOrchestratorAggregateSourceRequired);

            this.eventReconciler = ArgumentNotNull(
                eventReconciler,
                nameof(eventReconciler),
                DefaultReconciliationOrchestratorEventReconcilerRequired);

            this.sequenceFactory = ArgumentNotNull(
                sequenceFactory,
                nameof(sequenceFactory),
                DefaultReconciliationOrchestratorSequenceFactoryRequired);

            this.sequenceStore = ArgumentNotNull(
                sequenceStore,
                nameof(sequenceStore),
                DefaultReconciliationOrchestratorSequenceStoreRequired);

            this.snapshotSource = ArgumentNotNull(
                snapshotSource,
                nameof(snapshotSource),
                DefaultReconciliationOrchestratorSnapshotSourceRequired);

            this.aggregateReconciler.AggregateConflictDetected += AggregateReconciler_AggregateConflictDetected;
            this.eventReconciler.EventSequenceAdvanced         += EventReconciler_EventSequenceAdvanced;
        }
        public async Task <ISnapshot?> GenerateAsync(
            CancellationToken?cancellationToken = default,
            ulong?target = default)
        {
            IEventReconciler reconciler = CreateEventReconciler(
                out Func <Task <IEnumerable <EventCentricAggregateRoot> > > aggregates);

            ulong?current = await reconciler
                            .ReconcileAsync(
                cancellationToken : cancellationToken,
                target : target)
                            .ConfigureAwait(false);

            if (current.HasValue)
            {
                var sequence = new EventSequence(current.Value);

                IEnumerable <EventCentricAggregateRoot> values = await aggregates()
                                                                 .ConfigureAwait(false);

                return(new Snapshot(values, sequence));
            }

            return(default);