function createIterator(buffer) {
    'use strict';
    // Each tee'd iterator has an associated buffer (initially empty). When a
    // tee'd iterator's buffer is empty, it calls
    // addNextIteratorValueToBuffers(), adding the next value to all tee'd
    // iterators' buffers, and then returns that value. This allows each
    // iterator to be advanced independently.
    const iter =
        /** @type {!goog.iter.Iterator<VALUE>} */ (new goog.iter.Iterator());

    /**
     * @return {!IIterableResult<VALUE>}
     * @override
     */
    iter.next = function() {
      'use strict';
      if (goog.array.isEmpty(buffer)) {
        const added = addNextIteratorValueToBuffers();
        if (!added) return goog.iter.ES6_ITERATOR_DONE;
      }
      goog.asserts.assert(!goog.array.isEmpty(buffer));
      return goog.iter.createEs6IteratorYield(buffer.shift());
    };

    return iter;
  }
@param {!Array<VALUE>} buffer
@return {!goog.iter.Iterator<VALUE>}