/// <summary>
        ///     Uploads files from a specified directory.
        ///     The object key is derived from the file names
        ///     inside the directory.
        ///     For large uploads, the file will be divided and uploaded in parts using
        ///     Amazon S3's multipart API.  The parts will be reassembled as one object in
        ///     Amazon S3.
        /// </summary>
        /// <remarks>
        /// <para>
        /// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
        /// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
        /// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
        /// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
        /// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
        /// </para>
        /// </remarks>
        /// <param name="request">
        ///     The request that contains all the parameters required to upload a directory.
        /// </param>
        /// <param name="cancellationToken">
        ///     A cancellation token that can be used by other objects or threads to receive notice of cancellation.
        /// </param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public Task UploadDirectoryAsync(TransferUtilityUploadDirectoryRequest request, CancellationToken cancellationToken = default(CancellationToken))
        {
            validate(request);
            UploadDirectoryCommand command = new UploadDirectoryCommand(this, this._config, request);

            command.UploadFilesConcurrently = request.UploadFilesConcurrently;
            return(command.ExecuteAsync(cancellationToken));
        }