/// <summary>
        /// Use a HEAD bucket request to get the region for the given bucket.
        ///
        /// This method creates an AmazonS3Client from the credentials passed in.
        /// It's critical that the AmazonS3Client is not used to make any requests that will
        /// be routed through the pipeline.
        /// </summary>
        /// <param name="bucketName"></param>
        /// <param name="credentials"></param>
        /// <returns>the value of the x-amz-bucket-region header from the response</returns>
        private static string GetBucketRegionNoPipeline(string bucketName, ImmutableCredentials credentials)
        {
            var headBucketPreSignedUrl = GetHeadBucketPreSignedUrl(bucketName, credentials);

            using (var s3Client = GetUsEast1ClientFromCredentials(credentials))
            {
                var response = AmazonS3HttpUtil.GetHead(s3Client, s3Client.Config, headBucketPreSignedUrl, HeaderKeys.XAmzBucketRegion);
                return(response.HeaderValue);
            }
        }
        /// <summary>
        /// Determines whether an S3 bucket exists or not.
        /// This is done by:
        /// 1. Creating a PreSigned Url for the bucket. To work with Signature V4 only regions, as
        /// well as Signature V4-optional regions, we keep the expiry to within the maximum for V4
        /// (which is one week).
        /// 2. Making a HEAD request to the Url
        /// </summary>
        /// <param name="bucketName">The name of the bucket to check.</param>
        /// <param name="s3Client">The Amazon S3 Client to use for S3 specific operations.</param>
        /// <returns></returns>
        public static bool DoesS3BucketExist(IAmazonS3 s3Client, string bucketName)
        {
            if (s3Client == null)
            {
                throw new ArgumentNullException("s3Client", "The s3Client cannot be null!");
            }

            if (String.IsNullOrEmpty(bucketName))
            {
                throw new ArgumentNullException("bucketName", "The bucketName cannot be null or the empty string!");
            }

            var request = new GetPreSignedUrlRequest
            {
                BucketName = bucketName,
                Expires    = DateTime.Now.AddDays(1),
                Verb       = HttpVerb.HEAD,
                Protocol   = Protocol.HTTP
            };

            var url = s3Client.GetPreSignedURL(request);
            var uri = new Uri(url);

            var config   = s3Client.Config;
            var response = AmazonS3HttpUtil.GetHead(s3Client, config, url, HeaderKeys.XAmzBucketRegion);

            if (response.StatusCode == null)
            {
                // there was a problem with the request and we weren't able
                // conclusively determine if the bucket exists
                return(false);
            }
            else
            {
                AmazonS3Uri s3Uri;
                var         mismatchDetected = AmazonS3Uri.TryParseAmazonS3Uri(uri, out s3Uri) &&
                                               BucketRegionDetector.GetCorrectRegion(s3Uri, response.StatusCode.Value, response.HeaderValue) != null;
                var statusCodeAcceptable = response.StatusCode != HttpStatusCode.NotFound && response.StatusCode != HttpStatusCode.BadRequest;
                return(statusCodeAcceptable || mismatchDetected);
            }
        }