     }
 
     /// Resume the task awaiting the next iteration point by having it return
-    /// nil or throw which signifies the end of the iteration.
-    ///
-    /// - Parameter error: The error to throw or nil to signify termination.
-    ///
-    /// Calling this function more than once is idempotent; i.e. finishing more
-    /// than once does not alter the state beyond the requirements of
-    /// AsyncSequence; which claims that all values past a terminal state are
-    /// nil.
+    /// nil, which signifies the end of the iteration.
+    ///
+    /// - Parameter error: The error to throw, or `nil`, to finish normally.
+    ///
+    /// Calling this function more than once has no effect. After calling
+    /// finish, the stream enters a terminal state and doesn't produce any additional
+    /// elements.
     public func finish(throwing error: __owned Failure? = nil) {
       storage.finish(throwing: error)
     }
 
-    /// A callback to invoke when iteration of a AsyncThrowingStream is 
-    /// cancelled.
-    ///
-    /// If an `onTermination` callback is set, when iteration of a AsyncStream 
-    /// is cancelled via task cancellation that callback is invoked. The
-    /// callback is disposed of after any terminal state is reached.
-    ///
-    /// Cancelling an active iteration will first invoke the onTermination 
-    /// callback and then resume yeilding nil. This means that any cleanup state
-    /// can be emitted accordingly in the cancellation handler
+    /// A callback to invoke when canceling iteration of an asynchronous
+    /// stream.
+    ///
+    /// If an `onTermination` callback is set, using task cancellation to
+    /// terminate iteration of an `AsyncThrowingStream` results in a call to this
+    /// callback.
+    ///
+    /// Canceling an active iteration invokes the `onTermination` callback
+    /// first, and then resumes by yielding `nil` or throwing an error from the
+    /// iterator. This means that you can perform needed cleanup in the
+    ///  cancellation handler. After reaching a terminal state, the
+    ///  `AsyncThrowingStream` disposes of the callback.
     public var onTermination: (@Sendable (Termination) -> Void)? {
       get {
         return storage.getOnTermination()


import Swift

@available(SwiftStdlib 5.1, *)
public struct AsyncThrowingStream<Element, Failure: Error> {
  public struct Continuation: Sendable {
    /// Indication of the type of termination informed to
    /// `onTermination`.
    public enum Termination {
      
      /// The stream was finished via the `finish` method
      case finished(Failure?)
      
      /// The stream was cancelled
      case cancelled
    }
    
    /// A result of yielding values.
    public enum YieldResult {
      
      /// When a value is successfully enqueued, either buffered
      /// or immediately consumed to resume a pending call to next
      /// and a count of remaining slots available in the buffer at
      /// the point in time of yielding. Note: transacting upon the
      /// remaining count is only valid when then calls to yield are
      /// mutually exclusive.
      case enqueued(remaining: Int)
      
      /// Yielding resulted in not buffering an element because the
      /// buffer was full. The element is the dropped value.
      case dropped(Element)
      
      /// Indication that the continuation was yielded when the
      /// stream was already in a terminal state: either by cancel or
      /// by finishing.
      case terminated
    }
    
    /// A strategy that handles exhaustion of a buffer’s capacity.
    public enum BufferingPolicy {
      case unbounded
      
      /// When the buffer is full, discard the newly received element.
      /// This enforces keeping the specified amount of oldest values.
      case bufferingOldest(Int)
      
      /// When the buffer is full, discard the oldest element in the buffer.
      /// This enforces keeping the specified amount of newest values.
      case bufferingNewest(Int)
    }

    let storage: _Storage

    /// Resume the task awaiting the next iteration point by having it return
    /// normally from its suspension point or buffer the value if no awaiting
    /// next iteration is active.
    ///
    /// - Parameter value: The value to yield from the continuation.
    ///
    /// This can be called more than once and returns to the caller immediately
    /// without blocking for any awaiting consumption from the iteration.


  let produce: () async throws -> Element?

  /// Constructs an asynchronous stream for an element type, using the
  /// specified buffering policy and element-producing closure.
  ///
  /// - Parameters:
  ///   - elementType: The type of element the `AsyncThrowingStream`
  ///   produces.
  ///   - limit: The maximum number of elements to
  ///   hold in the buffer. By default, this value is unlimited. Use a
  ///   `Continuation.BufferingPolicy` to buffer a specified number of oldest
  ///   or newest elements.
  ///   - build: A custom closure that yields values to the
  ///   `AsyncThrowingStream`. This closure receives an
  ///   `AsyncThrowingStream.Continuation` instance that it uses to provide
  ///   elements to the stream and terminate the stream when finished.
  ///
  /// The `AsyncStream.Continuation` received by the `build` closure is
  /// appopriate for use in concurrent contexts. It is thread safe to send and
  /// finish; all calls are to the continuation are serialized. However, calling
  /// this from multiple concurrent contexts could result in out-of-order
  /// delivery.
  ///
  /// The following example shows an `AsyncStream` created with this
  /// initializer that produces 100 random numbers on a one-second interval,
  /// calling `yield(_:)` to deliver each element to the awaiting call point.
  /// When the `for` loop exits and the stream finishes by calling the
  /// continuation's `finish()` method. If the random number is divisble by 5
  /// with no remainder, the stream throws a `MyRandomNumberError`.
  ///
  ///     let stream = AsyncThrowingStream<Int, Error>(Int.self,
  ///                                                  bufferingPolicy: .bufferingNewest(5)) { continuation in
  ///             Task.detached {
  ///                 for _ in 0..<100 {
  ///                     await Task.sleep(1 * 1_000_000_000)
  ///                     let random = Int.random(in: 1...10)
  ///                     if (random % 5 == 0) {
  ///                         continuation.finish(throwing: MyRandomNumberError())
  ///                         return
  ///                     } else {
  ///                         continuation.yield(random)
  ///                     }
  ///                 }
  ///                 continuation.finish()
  ///             }
  ///         }
  ///
  ///     // Call point:
  ///     do {
  ///         for try await random in stream {
  ///             print ("\(random)")
  ///         }
  ///     } catch {
  ///         print ("\(error)")
  ///     }
  ///
  public init(
    _ elementType: Element.Type = Element.self,
    bufferingPolicy limit: Continuation.BufferingPolicy = .unbounded,
