message: simplified iterators
diff: */
  /**
  - * ES6 compatible mutable iterator. Use with care.
  + * ES6 compatible iterator.
  *
  - * "Idiomatic" usage:
  + * "Idiomatic" usage is to use the move function, because it does not make any allocations.
  *
  * const it = ...;
  - * for (let v = it.nextValue(); !it.done; v = it.nextValue()) { ... }
  + * for (let v = it.move(); it.hasNext; v = it.move()) { ... }
  */
  interface Iterator<T> {
  [Symbol.iterator](): Iterator<T>,
  - readonly done: boolean,
  - readonly value: T,
  + readonly hasNext: boolean,
  next(): { done: boolean, value: T },
  - nextValue(): T
  + move(): T
  }
  class ArrayIteratorImpl<T> implements Iterator<T> {
  private xs: ArrayLike<T> = [];
  private index: number = -1;
  private length: number = 0;
  + private lastValue: T;
  [Symbol.iterator]() { return this; };
  - done = true;
  - value: T = void 0 as any;
  + hasNext: boolean;
  next() {
  - const index = ++this.index;
  - if (index < this.length) this.value = this.xs[index];
  - else this.done = true;
  - return this;
  + const value = this.move();
  + return { value, done: !this.hasNext };
  }
  - nextValue() { return this.next().value; }
  + move() {
  + const index = ++this.index;
  + if (index < this.length) this.lastValue = this.xs[index];
  + else this.hasNext = false;
  + return this.lastValue;
  + }
  constructor(xs: ArrayLike<T>) {
  this.length = xs.length;
  - this.done = false;
  + this.hasNext = xs.length > 0;
  this.xs = xs;
  this.index = -1;
  + // try to avoid deoptimization with undefined values
  + this.lastValue = xs.length > 0 ? xs[0] : void 0 as any;
  return this;
  }
  }
  class RangeIteratorImpl implements Iterator<number> {
  + private value: number;
  +
  [Symbol.iterator]() { return this; };
  - done = true;
  - value: number;
  + hasNext: boolean;
  next() {
  - ++this.value;
  - this.done = this.value > this.max;
  - return this;
  + const value = this.value;
  + return { value, done: !this.hasNext }
  }
  - nextValue() { return this.next().value; }
  + move() {
  + ++this.value;
  + this.hasNext = this.value <= this.max;
  + return this.value;
  + }
  constructor(min: number, private max: number) {
  this.value = min - 1;
  - this.done = false;
  + this.hasNext = max >= min;
  return this;
  }
  }
  @@ -75,7 +83,7 @@ namespace Iterator {
  export function toArray<T>(it: Iterator<T>): T[] {
  const ret = [];
  - for (let v = it.nextValue(); !it.done; v = it.nextValue()) ret[ret.length] = v;
  + for (let v = it.move(); it.hasNext; v = it.move()) ret[ret.length] = v;
  return ret;
  }
  }
  