public void ExceptionTest()
        {
            using (var dummy = new MemoryStream())
            {
                ReadAsyncCallback  fakeRead  = (b, o, c, t) => Task.FromResult(0);
                WriteAsyncCallback fakeWrite = (b, o, c, t) => Task.FromResult(false);
                AssertThrow <NotSupportedException>(() => new S101Client(dummy, fakeRead, fakeWrite).Dispose());

                AsyncPump.Run(
                    async() =>
                {
                    using (var connection = new CompleteOnDispose())
                        using (var client = new S101Client(connection, (b, o, c, t) => connection.Task, fakeWrite))
                        {
                            await AssertThrowAsync <InvalidOperationException>(
                                () => Task.Run(() => client.SendMessageAsync(new S101Message(0x00, new KeepAliveRequest()))));
                        }

                    AssertThrow <ArgumentNullException>(
                        () => new S101Client(null, fakeRead, fakeWrite).Dispose(),
                        () => new S101Client(dummy, null, fakeWrite).Dispose(),
                        () => new S101Client(dummy, fakeRead, null).Dispose());

                    AssertThrow <ArgumentOutOfRangeException>(
                        () => new S101Client(dummy, fakeRead, fakeWrite, null, 3000, 0).Dispose(),
                        () => new S101Client(dummy, fakeRead, fakeWrite, null, -2, 1).Dispose());

                    using (var connection = new CompleteOnDispose())
                        using (var client = new S101Client(
                                   connection, (b, o, c, t) => connection.Task, fakeWrite, null, 3000, 1))
                        {
                            await AssertThrowAsync <ArgumentNullException>(
                                () => client.SendMessageAsync(null));
                            await AssertThrowAsync <ArgumentException>(() => client.SendMessageAsync(EmberDataMessage));
                            await AssertThrowAsync <ArgumentException>(() => client.SendOutOfFrameByteAsync(0xFE));

                            client.Dispose();
                            await AssertThrowAsync <ObjectDisposedException>(
                                () => client.SendMessageAsync(new S101Message(0x00, new KeepAliveRequest())));
                        }
                });
            }
        }
        /// <summary>Gets a <see cref="S101Client"/> object, which receives the message contained in
        /// <paramref name="messageStream"/> as soon as a message has been sent by calling
        /// <see cref="S101Client.SendMessageAsync(S101Message)"/>.</summary>
        protected static S101Client GetFakeClient(Stream messageStream, IS101Logger logger)
        {
            var disposable      = new CompleteOnDispose();
            var requestReceived = new TaskCompletionSource <bool>();

            ReadAsyncCallback read =
                async(b, o, c, t) =>
            {
                await requestReceived.Task;
                return(await Read(messageStream, b, o, c, t, disposable.Task));
            };

            WriteAsyncCallback write =
                (b, o, c, t) =>
            {
                requestReceived.SetResult(true);
                return(Task.FromResult(false));
            };

            return(new S101Client(disposable, read, write, logger, -1, 8192));
        }
        public void ExceptionTest()
        {
            using (var dummy = new MemoryStream())
            {
                ReadAsyncCallback fakeRead = (b, o, c, t) => Task.FromResult(0);
                WriteAsyncCallback fakeWrite = (b, o, c, t) => Task.FromResult(false);
                AssertThrow<NotSupportedException>(() => new S101Client(dummy, fakeRead, fakeWrite).Dispose());

                AsyncPump.Run(
                    async () =>
                    {
                        using (var connection = new CompleteOnDispose())
                        using (var client = new S101Client(connection, (b, o, c, t) => connection.Task, fakeWrite))
                        {
                            await AssertThrowAsync<InvalidOperationException>(
                                () => Task.Run(() => client.SendMessageAsync(new S101Message(0x00, new KeepAliveRequest()))));
                        }

                        AssertThrow<ArgumentNullException>(
                            () => new S101Client(null, fakeRead, fakeWrite).Dispose(),
                            () => new S101Client(dummy, null, fakeWrite).Dispose(),
                            () => new S101Client(dummy, fakeRead, null).Dispose());

                        AssertThrow<ArgumentOutOfRangeException>(
                            () => new S101Client(dummy, fakeRead, fakeWrite, null, 3000, 0).Dispose(),
                            () => new S101Client(dummy, fakeRead, fakeWrite, null, -2, 1).Dispose());

                        using (var connection = new CompleteOnDispose())
                        using (var client = new S101Client(
                            connection, (b, o, c, t) => connection.Task, fakeWrite, null, 3000, 1))
                        {
                            await AssertThrowAsync<ArgumentNullException>(
                                () => client.SendMessageAsync(null));
                            await AssertThrowAsync<ArgumentException>(() => client.SendMessageAsync(EmberDataMessage));
                            await AssertThrowAsync<ArgumentException>(() => client.SendOutOfFrameByteAsync(0xFE));

                            client.Dispose();
                            await AssertThrowAsync<ObjectDisposedException>(
                                () => client.SendMessageAsync(new S101Message(0x00, new KeepAliveRequest())));
                        }
                    });
            }
        }