private void DownloadObjectImpl(
            string baseUri,
            Stream destination,
            DownloadObjectOptions options,
            IProgress <IDownloadProgress> progress)
        {
            // URI will definitely not be null; that's constructed internally.
            GaxPreconditions.CheckNotNull(destination, nameof(destination));
            var downloader = new HashValidatingDownloader(Service);

            options?.ModifyDownloader(downloader);
            ApplyEncryptionKey(options?.EncryptionKey, downloader);
            string uri = options == null ? baseUri : options.GetUri(baseUri);

            if (progress != null)
            {
                downloader.ProgressChanged += progress.Report;
                progress.Report(InitialDownloadProgress.Instance);
            }
            var result = downloader.Download(uri, destination);

            if (result.Status == DownloadStatus.Failed)
            {
                throw result.Exception;
            }
        }
        private async Task DownloadObjectAsyncImpl(
            string baseUri,
            Stream destination,
            DownloadObjectOptions options,
            CancellationToken cancellationToken,
            IProgress <IDownloadProgress> progress)
        {
            GaxPreconditions.CheckNotNull(destination, nameof(destination));
            var downloader = new HashValidatingDownloader(Service);

            options?.ModifyDownloader(downloader);
            ApplyEncryptionKey(options?.EncryptionKey, downloader);
            string uri = options == null ? baseUri : options.GetUri(baseUri);

            if (progress != null)
            {
                downloader.ProgressChanged += progress.Report;
                // Avoid reporting progress synchronously in the original call.
                await Task.Yield();

                progress.Report(InitialDownloadProgress.Instance);
            }
            var result = await downloader.DownloadAsync(uri, destination, cancellationToken).ConfigureAwait(false);

            if (result.Status == DownloadStatus.Failed)
            {
                throw result.Exception;
            }
        }
        private HashValidatingDownloader CreateDownloader(DownloadObjectOptions options)
        {
            var downloader = new HashValidatingDownloader(Service);

            downloader.ModifyRequest += _versionHeaderAction;
            options?.ModifyDownloader(downloader);
            ApplyEncryptionKey(options?.EncryptionKey, downloader);
            return(downloader);
        }