private async Task <IStreamQbservableProtocol> NegotiateClientAsync(Stream stream, IRemotingFormatter formatter, CancellationToken cancel)
        {
            Contract.Requires(stream != null);
            Contract.Requires(formatter != null);

            var id       = (string)Id;
            var protocol = StreamQbservableProtocolFactory.CreateClient(id, stream, formatter, cancel);

            var buffer = Encoding.ASCII.GetBytes(id);

            await protocol.SendAsync(BitConverter.GetBytes(id.Length), 0, 4).ConfigureAwait(false);

            await protocol.SendAsync(buffer, 0, buffer.Length).ConfigureAwait(false);

            await protocol.ReceiveAsync(buffer, 0, buffer.Length).ConfigureAwait(false);

            Contract.Assume(Encoding.ASCII.GetString(buffer) == id);

            return(protocol);
        }
        private static async Task <IStreamQbservableProtocol> NegotiateServerAsync(object baseId, Stream stream, IRemotingFormatter formatter, QbservableServiceOptions serviceOptions, CancellationToken cancel)
        {
            Contract.Requires(stream != null);
            Contract.Requires(formatter != null);
            Contract.Requires(serviceOptions != null);

            var protocol = StreamQbservableProtocolFactory.CreateServer(stream, formatter, serviceOptions, cancel);

            var lengthBuffer = new byte[4];

            await protocol.ReceiveAsync(lengthBuffer, 0, 4).ConfigureAwait(false);

            var length = BitConverter.ToInt32(lengthBuffer, 0);

            if (length <= 0 || length > 255)
            {
                throw new InvalidOperationException("Invalid client ID received. (" + length + " bytes)");
            }

            var clientIdBuffer = new byte[length];

            await protocol.ReceiveAsync(clientIdBuffer, 0, clientIdBuffer.Length).ConfigureAwait(false);

            var clientId = Encoding.ASCII.GetString(clientIdBuffer);

            if (clientId == null || string.IsNullOrWhiteSpace(clientId))
            {
                throw new InvalidOperationException("Invalid client ID received (empty or only whitespace).");
            }

            await protocol.SendAsync(clientIdBuffer, 0, clientIdBuffer.Length).ConfigureAwait(false);

            protocol.ClientId = baseId + " (" + clientId + ")";

            return(protocol);
        }