/// <summary>
 /// List all objects along with versions non-recursively in a bucket with a given prefix, optionally emulating a directory
 /// </summary>
 /// <param name="args">ListObjectsArgs Arguments Object with information like Bucket name, prefix, recursive listing, versioning</param>
 /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
 /// <returns>An observable of items that client can subscribe to</returns>
 public IObservable <VersionItem> ListObjectVersionsAsync(ListObjectsArgs args, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(Observable.Create <VersionItem>(
                async(obs, ct) =>
     {
         bool isRunning = true;
         var delimiter = (args.Recursive) ? string.Empty : "/";
         string marker = string.Empty;
         using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, ct))
         {
             while (isRunning)
             {
                 GetObjectListArgs goArgs = new GetObjectListArgs()
                                            .WithBucket(args.BucketName)
                                            .WithPrefix(args.Prefix)
                                            .WithDelimiter(delimiter)
                                            .WithVersions(args.Versions)
                                            .WithMarker(marker);
                 Tuple <ListVersionsResult, List <VersionItem> > objectList = await this.GetObjectVersionsListAsync(goArgs, cts.Token).ConfigureAwait(false);
                 ListObjectVersionResponse listObjectsItemResponse = new ListObjectVersionResponse(args, objectList, obs);
                 marker = listObjectsItemResponse.NextMarker;
                 isRunning = objectList.Item1.IsTruncated;
                 cts.Token.ThrowIfCancellationRequested();
             }
         }
     }));
 }
        /// <summary>
        /// Gets the list of objects in the bucket filtered by prefix
        /// </summary>
        /// <param name="bucketName">Bucket to list objects from</param>
        /// <param name="prefix">Filters all objects starting with a given prefix</param>
        /// <param name="delimiter">Delimit the output upto this character</param>
        /// <param name="marker">marks location in the iterator sequence</param>
        /// <returns>Task with a tuple populated with objects</returns>
        /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
        private async Task <Tuple <ListBucketResult, List <Item> > > GetObjectListAsync(string bucketName, string prefix, string delimiter, string marker, CancellationToken cancellationToken = default(CancellationToken))
        {
            var queryMap = new Dictionary <string, string>();
            // null values are treated as empty strings.
            GetObjectListArgs args = new GetObjectListArgs()
                                     .WithBucket(bucketName)
                                     .WithPrefix(prefix)
                                     .WithDelimiter(delimiter)
                                     .WithMarker(marker);

            return(await this.GetObjectListAsync(args, cancellationToken));
        }
        /// <summary>
        /// Gets the list of objects along with version IDs in the bucket filtered by prefix
        /// </summary>
        /// <param name="args">GetObjectListArgs Arguments Object with information like Bucket name, prefix, delimiter, marker, versions(get version IDs of the objects)</param>
        /// <returns>Task with a tuple populated with objects</returns>
        /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
        private async Task <Tuple <ListVersionsResult, List <VersionItem> > > GetObjectVersionsListAsync(GetObjectListArgs args, CancellationToken cancellationToken = default(CancellationToken))
        {
            RestRequest request = await this.CreateRequest(args).ConfigureAwait(false);

            IRestResponse response = await this.ExecuteTaskAsync(this.NoErrorHandlers, request, cancellationToken).ConfigureAwait(false);

            GetObjectsVersionsListResponse getObjectsListResponse = new GetObjectsVersionsListResponse(response.StatusCode, response.Content);

            return(getObjectsListResponse.ObjectsTuple);
        }