public async Task <ConnectionDescription> SendHelloAsync(IConnection connection, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(connection, nameof(connection));
            var authenticators = GetAuthenticators(connection.Settings);
            var helloCommand   = CreateInitialHelloCommand(authenticators, connection.Settings.LoadBalanced);
            var helloProtocol  = HelloHelper.CreateProtocol(helloCommand, _serverApi);
            var helloResult    = await HelloHelper.GetResultAsync(connection, helloProtocol, cancellationToken).ConfigureAwait(false);

            if (connection.Settings.LoadBalanced && !helloResult.ServiceId.HasValue)
            {
                throw new InvalidOperationException("Driver attempted to initialize in load balancing mode, but the server does not support this mode.");
            }

            return(new ConnectionDescription(connection.ConnectionId, helloResult));
        }
        public async Task <ConnectionDescription> InitializeConnectionAsync(IConnection connection, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(connection, nameof(connection));
            var authenticators = connection.Settings.AuthenticatorFactories.Select(f => f.Create()).ToList();
            var helloCommand   = CreateInitialHelloCommand(authenticators);
            var helloProtocol  = HelloHelper.CreateProtocol(helloCommand, _serverApi);
            var helloResult    = await HelloHelper.GetResultAsync(connection, helloProtocol, cancellationToken).ConfigureAwait(false);

            var buildInfoProtocol = CreateBuildInfoProtocol(_serverApi);
            var buildInfoResult   = new BuildInfoResult(await buildInfoProtocol.ExecuteAsync(connection, cancellationToken).ConfigureAwait(false));

            var description = new ConnectionDescription(connection.ConnectionId, helloResult, buildInfoResult);

            await AuthenticationHelper.AuthenticateAsync(connection, description, authenticators, cancellationToken).ConfigureAwait(false);

            var connectionIdServerValue = helloResult.ConnectionIdServerValue;

            if (connectionIdServerValue.HasValue)
            {
                description = UpdateConnectionIdWithServerValue(description, connectionIdServerValue.Value);
            }
            else
            {
                try
                {
                    var getLastErrorProtocol = CreateGetLastErrorProtocol(_serverApi);
                    var getLastErrorResult   = await getLastErrorProtocol
                                               .ExecuteAsync(connection, cancellationToken)
                                               .ConfigureAwait(false);

                    description = UpdateConnectionIdWithServerValue(description, getLastErrorResult);
                }
                catch
                {
                    // if we couldn't get the server's connection id, so be it.
                }
            }

            return(description);
        }