/// <summary>
        /// Receive all parts of a multi-part message from a remote socket in non-blocking mode.
        /// </summary>
        /// <remarks>
        /// The <paramref name="frameTimeout"/> will be used for each underlying Receive operation. If the timeout
        /// elapses before the last message is received, an incomplete message will be returned.
        /// </remarks>
        /// <param name="socket">A <see cref="Socket"/> object.</param>
        /// <param name="message">The <see cref="Message"/> to which message-parts will be appended.</param>
        /// <param name="frameTimeout">A <see cref="TimeSpan"/> specifying the receive timeout for each frame.</param>
        /// <returns>A <see cref="Message"/> containing newly received <see cref="Frame"/> objects.</returns>
        /// <exception cref="XsSocketException">An error occurred receiving data from a remote endpoint.</exception>
        /// <exception cref="ObjectDisposedException">The <see cref="Socket"/> has been closed.</exception>
        /// <exception cref="NotSupportedException">The current socket type does not support Receive operations.</exception>
        public static Message ReceiveMessage(this Socket socket, Message message, TimeSpan frameTimeout)
        {
            VerifySocket(socket);
            VerifyMessage(message);

            Frame frame;

            do
            {
                frame = socket.ReceiveFrame(frameTimeout);

                if (frame.ReceiveStatus == ReceiveStatus.Received)
                {
                    message.AppendShallowCopy(frame);
                }
            }
            while (frame.ReceiveStatus == ReceiveStatus.Received && frame.HasMore);

            return message;
        }