anchor.diff:  /// The compare function must act as a [Comparator]. If [compare] is omitted,
   /// [Comparable.compare] is used. If [i] contains null elements, an exception
   /// will be thrown.
  -dynamic max(Iterable i, [Comparator compare = Comparable.compare]) =>
  -    i.isEmpty ? null : i.reduce((a, b) => compare(a, b) > 0 ? a : b);
  +T max<T>(Iterable<T> i, [Comparator<T> compare]) {
  +  final Comparator<T> _compare = compare ?? Comparable.compare;
  +  return i.isEmpty ? null : i.reduce((a, b) => _compare(a, b) > 0 ? a : b);
  +}
   
   /// Returns the minimum value in [i], according to the order specified by the
   /// [compare] function, or `null` if [i] is empty.
  
positive.code: /// The compare function must act as a [Comparator]. If [compare] is omitted,
  /// [Comparable.compare] is used. If [i] contains null elements, an exception
  /// will be thrown.
  dynamic min(Iterable i, [Comparator compare = Comparable.compare]) =>
      i.isEmpty ? null : i.reduce((a, b) => compare(a, b) < 0 ? a : b);
  
  /// Returns the minimum and maximum values in [i], according to the order
  /// specified by the [compare] function, in an [Extent] instance. Always
  
negative.code: ///
  /// If [i] is empty, an [Extent] is returned with [:null:] values for [:min:]
  /// and [:max:], since there are no valid values for them.
  Extent<T> extent<T>(Iterable<T> i, [Comparator<T> compare]) {
    final Comparator<T> _compare = compare ?? Comparable.compare;
    var iterator = i.iterator;
    var hasNext = iterator.moveNext();
    if (!hasNext) return new Extent(null, null);
    var max = iterator.current;
    var min = iterator.current;
    while (iterator.moveNext()) {
      if (_compare(max, iterator.current) < 0) max = iterator.current;
      if (_compare(min, iterator.current) > 0) min = iterator.current;
    }
    return new Extent(min, max);
  }
  
  class Extent<T> {
    final T min;
    final T max;
    Extent(this.min, this.max);
  }
  