function Utf8IteratorImpl(upstream) {
	    var _this2;

	    _this2 = _OneToManyIterator.call(this) || this;
	    _this2.upstream = upstream;

	    if (env().get('IS_BROWSER')) {
	      _this2.decoder = new TextDecoder('utf-8');
	    } else {
	      // tslint:disable-next-line:no-require-imports
	      var _require = require('string_decoder'),
	          StringDecoder = _require.StringDecoder;

	      _this2.decoder = new StringDecoder('utf8');
	    }

	    return _this2;
	  }
Decode a stream of UTF8-encoded byte arrays to a stream of strings.

This is tricky because the incoming byte array boundaries may disrupt a
multi-byte UTF8 character. Thus any incomplete character data at the end of
a chunk must be carried over and prepended to the next chunk before
decoding. Luckily with native decoder, TextDecoder in browser and
string_decoder in node, byte array boundaries are handled automatically.

In the context of an input pipeline for machine learning, UTF8 decoding is
needed to parse text files containing training examples or prediction
requests (e.g., formatted as CSV or JSON). We cannot use the built-in
decoding provided by FileReader.readAsText() because here we are in a
streaming context, which FileReader does not support.

@param upstream A `LazyIterator` of `Uint8Arrays` containing UTF8-encoded
  text, which should be interpreted as concatenated.  No assumptions are
  made about the boundaries of the incoming chunks, so a multi-byte UTF8
  encoding of a character may span the boundary between chunks.  This
  naturally happens, for instance, when reading fixed-size byte arrays from a
  file.