/// <summary>
        /// Receive a series of messages until the function returns null or the idle
        /// timeout is met (disabled by default) or the overall
        /// maximum duration is elapsed or expected messages count is reached.
        /// Returns the sequence of messages.
        ///
        /// Note that it is not an error to hit the `max` duration in this case.
        /// The max duration is scaled by <see cref="Dilated(TimeSpan)"/>
        /// </summary>
        public IReadOnlyList <T> ReceiveWhile <T>(Func <object, T> filter, TimeSpan?max = null, TimeSpan?idle = null, int msgs = int.MaxValue) where T : class
        {
            var maxValue = RemainingOrDilated(max);
            var start    = Now;
            var stop     = start + maxValue;

            ConditionalLog("Trying to receive {0}messages of type {1} while filter returns non-nulls during {2}", msgs == int.MaxValue ? "" : msgs + " ", typeof(T), maxValue);
            var             count     = 0;
            var             acc       = new List <T>();
            var             idleValue = idle.GetValueOrDefault(Timeout.InfiniteTimeSpan);
            MessageEnvelope msg       = NullMessageEnvelope.Instance;

            while (count < msgs)
            {
                MessageEnvelope envelope;
                if (!TryReceiveOne(out envelope, (stop - Now).Min(idleValue)))
                {
                    _testState.LastMessage = msg;
                    break;
                }
                var message = envelope.Message;
                var result  = filter(message);
                if (result == null)
                {
                    _testState.Queue.AddFirst(envelope);  //Put the message back in the queue
                    _testState.LastMessage = msg;
                    break;
                }
                msg = envelope;
                acc.Add(result);
                count++;
            }
            ConditionalLog("Received {0} messages with filter during {1}", count, Now - start);

            _testState.LastWasNoMsg = true;
            return(acc);
        }
 /// <summary>
 /// Receive one message from the internal queue of the TestActor within
 /// the specified duration. The method blocks the specified duration.
 /// <remarks><b>Note!</b> that the returned <paramref name="envelope"/>
 /// is a <see cref="MessageEnvelope"/> containing the sender and the message.</remarks>
 /// <remarks>This method does NOT automatically scale its Duration parameter using <see cref="Dilated(TimeSpan)" />!</remarks>
 /// </summary>
 /// <param name="envelope">The received envelope.</param>
 /// <param name="max">Optional: The maximum duration to wait.
 ///     If <c>null</c> the config value "akka.test.single-expect-default" is used as timeout.
 ///     If set to a negative value or <see cref="Timeout.InfiniteTimeSpan"/>, blocks forever.
 ///     <remarks>This method does NOT automatically scale its Duration parameter using <see cref="Dilated(TimeSpan)" />!</remarks></param>
 /// <returns><c>True</c> if a message was received within the specified duration; <c>false</c> otherwise.</returns>
 public bool TryReceiveOne(out MessageEnvelope envelope, TimeSpan?max = null)
 {
     return(TryReceiveOne(out envelope, max, CancellationToken.None));
 }
 /// <summary>
 /// Receive one message from the internal queue of the TestActor within
 /// the specified duration.
 /// <para><c>True</c> is returned if a message existed, and the message
 /// is returned in <paramref name="envelope" />. The method blocks the
 /// specified duration, and can be cancelled using the
 /// <paramref name="cancellationToken" />.
 /// </para>
 /// <remarks>This method does NOT automatically scale its duration parameter using <see cref="Dilated(TimeSpan)" />!</remarks>
 /// </summary>
 /// <param name="envelope">The received envelope.</param>
 /// <param name="max">The maximum duration to wait.
 ///     If <c>null</c> the config value "akka.test.single-expect-default" is used as timeout.
 ///     If set to <see cref="Timeout.InfiniteTimeSpan"/>, blocks forever (or until cancelled).
 ///     <remarks>This method does NOT automatically scale its Duration parameter using <see cref="Dilated(TimeSpan)" />!</remarks>
 /// </param>
 /// <param name="cancellationToken">A token used to cancel the operation.</param>
 /// <returns><c>True</c> if a message was received within the specified duration; <c>false</c> otherwise.</returns>
 public bool TryReceiveOne(out MessageEnvelope envelope, TimeSpan?max, CancellationToken cancellationToken)
 {
     return(InternalTryReceiveOne(out envelope, max, cancellationToken, true));
 }