 
 import FirebaseStorage
 
-/// getResultCallback generates a closure that returns a Result type from a closure that returns an
-/// optional type and Error.
+/// Generates a closure that returns a `Result` type from a closure that returns an optional type
+/// and `Error`.
+///
+/// - Parameters:
+///   - completion: A completion block returning a `Result` enum with either a generic object or
+///                 an `Error`.
+/// - Returns: A closure parameterized with an optional generic and optional `Error` to match
+///            Objective C APIs.
 private func getResultCallback<T>(
   completion: @escaping (Result<T, Error>) -> Void
 ) -> (_: T?, _: Error?) -> Void {

                   completion: getResultCallback(completion: completion))
  }

  func updateMetadata(_ metadata: StorageMetadata,
                      completion: @escaping (Result<StorageMetadata, Error>) -> Void) {
    return updateMetadata(metadata, completion: getResultCallback(completion: completion))
  }

  func write(toFile: URL, completion: @escaping (Result<URL, Error>)
    -> Void) -> StorageDownloadTask {
    return write(toFile: toFile, completion: getResultCallback(completion: completion))

}

public extension StorageReference {
  /// Asynchronously retrieves a long lived download URL with a revokable token.
  /// This can be used to share the file with others, but can be revoked by a developer
  /// in the Firebase Console if desired.
  ///
  /// - Parameters:
  ///   - completion: A completion block returning a `Result` enum with either a URL or an `Error`.
  func downloadURL(completion: @escaping (Result<URL, Error>) -> Void) {
    downloadURL(completion: getResultCallback(completion: completion))
  }

  /// Asynchronously downloads the object at the `StorageReference` to a `Data` object.
  /// A `Data` of the provided max size will be allocated, so ensure that the device has enough
  /// memory to complete. For downloading large files, writeToFile may be a better option.

  /// - Parameters:
  ///   - maxSize: The maximum size in bytes to download.
  ///   - completion: A completion block returning a `Result` enum with either a `Data` object or
  ///                 an `Error`.
  ///
  /// - Returns: A StorageDownloadTask that can be used to monitor or manage the download.
  func getData(maxSize: Int64, completion: @escaping (Result<Data, Error>) -> Void)
    -> StorageDownloadTask {
    return getData(maxSize: maxSize, completion: getResultCallback(completion: completion))
  }

  /// Retrieves metadata associated with an object at the current path.
  ///
  /// - Parameters:
  ///   - completion: A completion block which returns a `Result` enum with either the
  ///                 object metadata or an `Error`.
  func getMetadata(completion: @escaping (Result<StorageMetadata, Error>) -> Void) {
    getMetadata(completion: getResultCallback(completion: completion))
  }

  /// Resumes a previous `list` call, starting after a pagination token.
  /// Returns the next set of items (files) and prefixes (folders) under this StorageReference.
  ///
  /// "/" is treated as a path delimiter. Firebase Storage does not support unsupported object
  /// paths that end with "/" or contain two consecutive "/"s. All invalid objects in GCS will be
  /// filtered.
  ///
  /// Only available for projects using Firebase Rules Version 2.
  ///
  /// - Parameters:
  ///   - withMaxResults The maximum number of results to return in a single page. Must be
  ///                    greater than 0 and at most 1000.
  ///   - pageToken A page token from a previous call to list.
  ///   - completion A completion handler that will be invoked with the next items and
  ///                prefixes under the current StorageReference. It returns a `Result` enum
  ///                with either the list or an `Error`.
  func list(withMaxResults maxResults: Int64,
            pageToken: String,
            completion: @escaping (Result<StorageListResult, Error>) -> Void) {
