/// <summary>
        /// Use to "wait" for an expected projection shard state
        /// </summary>
        /// <param name="expected"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public Task <ShardState> WaitForShardState(ShardState expected, TimeSpan?timeout = null)
        {
            timeout ??= 1.Minutes();
            var listener = new ShardStatusWatcher(this, expected, timeout.Value);

            return(listener.Task);
        }
        /// <summary>
        /// Use to "wait" for an expected projection shard condition
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="description"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public Task <ShardState> WaitForShardCondition(Func <ShardState, bool> condition, string description,
                                                       TimeSpan?timeout = null)
        {
            timeout ??= 1.Minutes();
            var listener = new ShardStatusWatcher(description, condition, this, timeout.Value);

            return(listener.Task);
        }
        /// <summary>
        /// Use to "wait" for an expected projection shard state
        /// </summary>
        /// <param name="expected"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public Task <ShardState> WaitForShardState(ShardState expected, TimeSpan?timeout = null)
        {
            if (_states.TryFind(expected.ShardName, out var state))
            {
                if (state.Equals(expected))
                {
                    return(Task.FromResult(state));
                }
            }

            timeout ??= 1.Minutes();
            var listener = new ShardStatusWatcher(this, expected, timeout.Value);

            return(listener.Task);
        }