Version 0.3.7.4
Merge revisions 18572, 18615, 18631 and 18633 to trunk.
Review URL: https://codereview.chromium.org//12296011

git-svn-id: http://dart.googlecode.com/svn/trunk@18642 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer-experimental/lib/src/generated/java_core.dart b/pkg/analyzer-experimental/lib/src/generated/java_core.dart
index 5d49598..7b148cb 100644
--- a/pkg/analyzer-experimental/lib/src/generated/java_core.dart
+++ b/pkg/analyzer-experimental/lib/src/generated/java_core.dart
@@ -303,7 +303,7 @@
     return elements.removeLast();
   }
 
-  List<E> get reversed => elements.reversed;
+  Iterable<E> get reversed => elements.reversed;
 
   List<E> getRange(int start, int length) {
     return elements.getRange(start, length);
diff --git a/pkg/http/lib/src/byte_stream.dart b/pkg/http/lib/src/byte_stream.dart
index 3ef0b6e..f6d87ff 100644
--- a/pkg/http/lib/src/byte_stream.dart
+++ b/pkg/http/lib/src/byte_stream.dart
@@ -35,5 +35,5 @@
       toBytes().then((bytes) => decodeString(bytes, encoding));
 
   Stream<String> toStringStream([Encoding encoding=Encoding.UTF_8]) =>
-      wrapStream(mappedBy((bytes) => decodeString(bytes, encoding)));
+      wrapStream(map((bytes) => decodeString(bytes, encoding)));
 }
diff --git a/pkg/serialization/lib/src/format.dart b/pkg/serialization/lib/src/format.dart
index a1726f0..68f6094 100644
--- a/pkg/serialization/lib/src/format.dart
+++ b/pkg/serialization/lib/src/format.dart
@@ -210,13 +210,13 @@
     // the data is shown to the user, so we destructively modify.
     if (data is List) {
       ruleNumber = data.last;
-      data = data.take(data.length -1);
+      data = data.take(data.length - 1).toList();
     } else if (data is Map) {
       ruleNumber = data.remove(RULE);
     } else {
       throw new SerializationException("Invalid data format");
     }
-    // Do not use mappedBy or other lazy operations for this. They do not play
+    // Do not use map or other lazy operations for this. They do not play
     // well with a function that destructively modifies its arguments.
     var newData = mapValues(data, (each) => recursivelyFixUp(each, r, result));
     result[ruleNumber].add(newData);
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index 3ce453b..1441dc2 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -104,10 +104,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(E element)) {
-    IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   reduce(initialValue, combine(previousValue, E element)) {
     return IterableMixinWorkaround.reduce(this, initialValue, combine);
   }
@@ -164,7 +160,7 @@
     return this.length == 0;
   }
 
-  List<E> get reversed => new ReversedListView<E>(this, 0, null);
+  Iterable<E> get reversed => new ReversedListIterable<E>(this);
 
   void sort([int compare(E a, E b)]) {
     IterableMixinWorkaround.sortList(this, compare);
@@ -338,10 +334,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(E element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   String join([String separator]) {
     return IterableMixinWorkaround.joinList(this, separator);
   }
@@ -402,7 +394,7 @@
     return this.length == 0;
   }
 
-  List<E> get reversed => new ReversedListView<E>(this, 0, null);
+  Iterable<E> get reversed => new ReversedListIterable<E>(this);
 
   void sort([int compare(E a, E b)]) {
     throw new UnsupportedError(
diff --git a/runtime/lib/byte_array.dart b/runtime/lib/byte_array.dart
index 14b1b17..7eb126a 100644
--- a/runtime/lib/byte_array.dart
+++ b/runtime/lib/byte_array.dart
@@ -233,10 +233,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(int element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   String join([String separator]) {
     return IterableMixinWorkaround.join(this, separator);
   }
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 5bd8987..27699e2 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -246,10 +246,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(T element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   reduce(initialValue, combine(previousValue, T element)) {
     return IterableMixinWorkaround.reduce(this, initialValue, combine);
   }
@@ -310,7 +306,7 @@
     this.length = 0;
   }
 
-  List<T> get reversed => new ReversedListView<T>(this, 0, null);
+  Iterable<T> get reversed => new ReversedListIterable<T>(this);
 
   void sort([int compare(T a, T b)]) {
     IterableMixinWorkaround.sortList(this, compare);
diff --git a/runtime/lib/string_buffer_patch.dart b/runtime/lib/string_buffer_patch.dart
index 841fc4f..ac700bf 100644
--- a/runtime/lib/string_buffer_patch.dart
+++ b/runtime/lib/string_buffer_patch.dart
@@ -2,58 +2,45 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-patch /* abstract */ class StringBuffer {
-  /* patch */ factory StringBuffer([Object content = ""])
-    => new _StringBufferImpl(content);
-}
-
-class _StringBufferImpl implements StringBuffer {
-
+patch class StringBuffer {
   List<String> _buffer;
   int _length;
 
   /// Creates the string buffer with an initial content.
-  _StringBufferImpl(Object content) {
-    clear();
-    add(content);
+  /* patch */ StringBuffer([Object content = ""]) {
+    _buffer = new List<String>();
+    _length = 0;
+    write(content);
   }
 
-  /// Returns the length of the buffer.
-  int get length => _length;
-
-  bool get isEmpty => _length == 0;
+  /* patch */ int get length => _length;
 
   /// Adds [obj] to the buffer.
-  void add(Object obj) {
+  /* patch */ void write(Object obj) {
     // TODO(srdjan): The following four lines could be replaced by
     // '$obj', but apparently this is too slow on the Dart VM.
-    String str = obj.toString();
-    if (str is !String) {
-      throw new ArgumentError('toString() did not return a string');
+    String str;
+    if (obj is String) {
+      str = obj;
+    } else {
+      str = obj.toString();
+      if (str is! String) {
+        throw new ArgumentError('toString() did not return a string');
+      }
     }
     if (str.isEmpty) return;
     _buffer.add(str);
     _length += str.length;
   }
 
-  /// Adds all items in [objects] to the buffer.
-  void addAll(Iterable objects) {
-    for (Object obj in objects) add(obj);
-  }
-
-  /// Adds the string representation of [charCode] to the buffer.
-  void addCharCode(int charCode) {
-    add(new String.fromCharCodes([charCode]));
-  }
-
   /// Clears the string buffer.
-  void clear() {
+  /* patch */ void clear() {
     _buffer = new List<String>();
     _length = 0;
   }
 
   /// Returns the contents of buffer as a concatenated string.
-  String toString() {
+  /* patch */ String toString() {
     if (_buffer.length == 0) return "";
     if (_buffer.length == 1) return _buffer[0];
     String result = Strings.concatAll(_buffer);
diff --git a/sdk/lib/_collection_dev/iterable.dart b/sdk/lib/_collection_dev/iterable.dart
index 676ad73..bf6c85e 100644
--- a/sdk/lib/_collection_dev/iterable.dart
+++ b/sdk/lib/_collection_dev/iterable.dart
@@ -4,7 +4,6 @@
 
 part of dart._collection.dev;
 
-
 /**
  * An [Iterable] for classes that have efficient [length] and [elementAt].
  *
@@ -15,7 +14,7 @@
   int get length;
   E elementAt(int i);
 
-  Iterator<E> get iterator => new ListIterableIterator<E>(this);
+  Iterator<E> get iterator => new ListIterator<E>(this);
 
   void forEach(void action(E element)) {
     int length = this.length;
@@ -93,7 +92,7 @@
 
   E lastMatching(bool test(E element), { E orElse() }) {
     int length = this.length;
-    for (int i = length - 1; i >= 0; i++) {
+    for (int i = length - 1; i >= 0; i--) {
       E element = elementAt(i);
       if (test(element)) return element;
       if (length != this.length) {
@@ -196,15 +195,13 @@
 
   Iterable<E> where(bool test(E element)) => super.where(test);
 
-  Iterable map(f(E element)) => new MappedIterable(this, f);
-
-  Iterable mappedBy(f(E element)) => super.mappedBy(f);
+  Iterable map(f(E element)) => new MappedListIterable(this, f);
 
   reduce(var initialValue, combine(var previousValue, E element)) {
     var value = initialValue;
     int length = this.length;
     for (int i = 0; i < length; i++) {
-      value = reduce(value, elementAt(i));
+      value = combine(value, elementAt(i));
       if (length != this.length) {
         throw new ConcurrentModificationError(this);
       }
@@ -237,7 +234,7 @@
   }
 }
 
-abstract class SubListIterable<E> extends ListIterable<E> {
+class SubListIterable<E> extends ListIterable<E> {
   final Iterable<E> _iterable;
   final int _start;
   /** If null, represents the length of the iterable. */
@@ -284,19 +281,27 @@
     if (_endOrLength == null) {
       return new SubListIterable(_iterable, _start, _start + count);
     } else {
-      newEnd = _start + count;
+      int newEnd = _start + count;
       if (_endOrLength < newEnd) return this;
       return new SubListIterable(_iterable, _start, newEnd);
     }
   }
 }
 
-class ListIterableIterator<E> implements Iterator<E> {
+/**
+ * An [Iterator] that iterates a list-like [Iterable].
+ *
+ * All iterations is done in terms of [Iterable.length] and
+ * [Iterable.elementAt]. These operations are fast for list-like
+ * iterables.
+ */
+class ListIterator<E> implements Iterator<E> {
   final Iterable<E> _iterable;
   final int _length;
   int _index;
   E _current;
-  ListIterableIterator(Iterable<E> iterable)
+
+  ListIterator(Iterable<E> iterable)
       : _iterable = iterable, _length = iterable.length, _index = 0;
 
   E get current => _current;
@@ -330,8 +335,13 @@
   // Length related functions are independent of the mapping.
   int get length => _iterable.length;
   bool get isEmpty => _iterable.isEmpty;
-}
 
+  // Index based lookup can be done before transforming.
+  T get first => _f(_iterable.first);
+  T get last => _f(_iterable.last);
+  T get single => _f(_iterable.single);
+  T elementAt(int index) => _f(_iterable.elementAt(index));
+}
 
 class MappedIterator<S, T> extends Iterator<T> {
   T _current;
@@ -346,344 +356,27 @@
     if (_iterator.moveNext()) {
       _current = _f(_iterator.current);
       return true;
-    } else {
-      _current = null;
-      return false;
     }
+    _current = null;
+    return false;
   }
 
   T get current => _current;
 }
 
 /** Specialized alternative to [MappedIterable] for mapped [List]s. */
-class MappedListIterable<S, T> extends Iterable<T> {
-  final List<S> _list;
-  /**
-   * Start index of the part of the list to map.
-   *
-   * Allows mapping only a sub-list of an existing list.
-   *
-   * Used to implement lazy skip/take on a [MappedListIterable].
-   */
-  final int _start;
-
-  /**
-   * End index of the part of the list to map.
-   *
-   * If null, always use the length of the list.
-   */
-  final int _end;
-
+class MappedListIterable<S, T> extends ListIterable<T> {
+  final Iterable<S> _source;
   // TODO(ahe): Restore type when feature is implemented in dart2js
   // checked mode. http://dartbug.com/7733
   final /* _Transformation<S, T> */ _f;
 
-  MappedListIterable(this._list, T this._f(S element), this._start, this._end) {
-    if (_end != null && _end < _start) {
-      throw new ArgumentError("End ($_end) before start ($_start)");
-    }
-  }
+  MappedListIterable(this._source, T this._f(S value));
 
-  /** The start index, limited to the current length of the list. */
-  int get _startIndex {
-    if (_start <= _list.length) return _start;
-    return _list.length;
-  }
-
-  /** The end index, if given, limited to the current length of the list. */
-  int get _endIndex {
-    if (_end == null || _end > _list.length) return _list.length;
-    return _end;
-  }
-
-  Iterator<T> get iterator =>
-      new MappedListIterator<S, T>(_list, _f, _startIndex, _endIndex);
-
-  void forEach(void action(T element)) {
-    int length = _list.length;
-    for (int i = _startIndex, n = _endIndex; i < n; i++) {
-      action(_f(_list[i]));
-      if (_list.length != length) {
-        throw new ConcurrentModificationError(_list);
-      }
-    }
-  }
-
-  bool get isEmpty => _startIndex == _endIndex;
-
-  int get length => _endIndex - _startIndex;
-
-  T get first {
-    int start = _startIndex;
-    if (start == _endIndex) {
-      throw new StateError("No elements");
-    }
-    return _f(_list.elementAt(start));
-  }
-
-  T get last {
-    int end = _endIndex;
-    if (end == _startIndex) {
-      throw new StateError("No elements");
-    }
-    return _f(_list.elementAt(end - 1));
-  }
-
-  T get single {
-    int start = _startIndex;
-    int end = _endIndex;
-    if (start != end - 1) {
-      if (start == end) {
-        throw new StateError("No elements");
-      }
-      throw new StateError("Too many elements");
-    }
-    return _f(_list[start]);
-  }
-
-  T elementAt(int index) {
-    index += _startIndex;
-    if (index >= _endIndex) {
-      throw new StateError("No matching element");
-    }
-    return _f(_list.elementAt(index));
-  }
-
-  bool contains(T element) {
-    int length = _list.length;
-    for (int i = _startIndex, n = _endIndex; i < n; i++) {
-      if (_f(_list[i]) == element) {
-        return true;
-      }
-      if (_list.length != length) {
-        throw new ConcurrentModificationError(_list);
-      }
-    }
-    return false;
-  }
-
-  bool every(bool test(T element)) {
-    int length = _list.length;
-    for (int i = _startIndex, n = _endIndex; i < n; i++) {
-      if (!test(_f(_list[i]))) return false;
-      if (_list.length != length) {
-        throw new ConcurrentModificationError(_list);
-      }
-    }
-    return true;
-  }
-
-  bool any(bool test(T element)) {
-    int length = _list.length;
-    for (int i = _startIndex, n = _endIndex; i < n; i++) {
-      if (test(_f(_list[i]))) return true;
-      if (_list.length != length) {
-        throw new ConcurrentModificationError(_list);
-      }
-    }
-    return false;
-  }
-
-  T firstMatching(bool test(T element), { T orElse() }) {
-    int length = _list.length;
-    for (int i = _startIndex, n = _endIndex; i < n; i++) {
-      T value = _f(_list[i]);
-      if (test(value)) return value;
-      if (_list.length != length) {
-        throw new ConcurrentModificationError(_list);
-      }
-    }
-    if (orElse != null) return orElse();
-    throw new StateError("No matching element");
-  }
-
-  T lastMatching(bool test(T element), { T orElse() }) {
-    int length = _list.length;
-    for (int i = _endIndex - 1, start = _startIndex; i >= start; i++) {
-      T value = _f(_list[i]);
-      if (test(value)) return value;
-      if (_list.length != length) {
-        throw new ConcurrentModificationError(_list);
-      }
-    }
-    if (orElse != null) return orElse();
-    throw new StateError("No matching element");
-  }
-
-  T singleMatching(bool test(T element)) {
-    int length = _list.length;
-    T match;
-    bool matchFound = false;
-    for (int i = _startIndex, n = _endIndex; i < n; i++) {
-      T value = _f(_list[i]);
-      if (test(value)) {
-        if (matchFound) {
-          throw new StateError("More than one matching element");
-        }
-        matchFound = true;
-        match = value;
-      }
-      if (_list.length != length) {
-        throw new ConcurrentModificationError(_list);
-      }
-    }
-    if (matchFound) return match;
-    throw new StateError("No matching element");
-  }
-
-  T min([int compare(T a, T b)]) {
-    if (compare == null) {
-      var defaultCompare = Comparable.compare;
-      compare = defaultCompare;
-    }
-    int length = _list.length;
-    int start = _startIndex;
-    int end = _endIndex;
-    if (start == end) return null;
-    T value = _f(_list[start]);
-    if (_list.length != length) {
-      throw new ConcurrentModificationError(_list);
-    }
-    for (int i = start + 1; i < end; i++) {
-      T nextValue = _f(_list[i]);
-      if (compare(value, nextValue) > 0) {
-        value = nextValue;
-      }
-      if (_list.length != length) {
-        throw new ConcurrentModificationError(_list);
-      }
-    }
-    return value;
-  }
-
-  T max([int compare(T a, T b)]) {
-    if (compare == null) {
-      var defaultCompare = Comparable.compare;
-      compare = defaultCompare;
-    }
-    int length = _list.length;
-    int start = _startIndex;
-    int end = _endIndex;
-    if (start == end) return null;
-    T value = _f(_list[start]);
-    if (_list.length != length) {
-      throw new ConcurrentModificationError(_list);
-    }
-    for (int i = start + 1; i < end; i++) {
-      T nextValue = _f(_list[i]);
-      if (compare(value, nextValue) < 0) {
-        value = nextValue;
-      }
-      if (_list.length != length) {
-        throw new ConcurrentModificationError(_list);
-      }
-    }
-    return value;
-  }
-
-  String join([String separator]) {
-    int start = _startIndex;
-    int end = _endIndex;
-    if (start == end) return "";
-    StringBuffer buffer = new StringBuffer("${_f(_list[start])}");
-    if (_list.length != length) {
-      throw new ConcurrentModificationError(_list);
-    }
-    for (int i = start + 1; i < end; i++) {
-      if (separator != null && separator != "") {
-        buffer.add(separator);
-      }
-      buffer.add("${_f(_list[i])}");
-      if (_list.length != length) {
-        throw new ConcurrentModificationError(_list);
-      }
-    }
-    return buffer.toString();
-  }
-
-  Iterable<T> where(bool test(T element)) => super.where(test);
-
-  Iterable map(f(T element)) {
-    return new MappedListIterable(_list, (S v) => f(_f(v)), _start, _end);
-  }
-
-  Iterable mappedBy(f(T element)) => map(f);
-
-  reduce(var initialValue, combine(var previousValue, T element)) {
-    return _list.reduce(initialValue, (v, S e) => combine(v, _f(e)));
-  }
-
-  Iterable<T> skip(int count) {
-    int start = _startIndex + count;
-    if (_end != null && start >= _end) {
-      return new EmptyIterable<T>();
-    }
-    return new MappedListIterable(_list, _f, start, _end);
-  }
-
-  Iterable<T> skipWhile(bool test(T element)) => super.skipWhile(test);
-
-  Iterable<T> take(int count)  {
-    int newEnd = _start + count;
-    if (_end == null || newEnd < _end)  {
-      return new MappedListIterable(_list, _f, _start, newEnd);
-    }
-    // Equivalent to "this".
-    return new MappedListIterable(_list, _f, _start, _end);
-  }
-
-  Iterable<T> takeWhile(bool test(T element)) => super.takeWhile(test);
-
-  List<T> toList() {
-    List<T> result = new List<T>();
-    forEach(result.add);
-    return result;
-  }
-
-  Set<T> toSet() {
-    Set<T> result = new Set<T>();
-    forEach(result.add);
-    return result;
-  }
+  int get length => _source.length;
+  T elementAt(int index) => _f(_source.elementAt(index));
 }
 
-/**
- * Iterator for [MappedListIterable].
- *
- * A list iterator that iterates over (a sublist of) a list and
- * returns the values transformed by a function.
- *
- * As a list iterator, it throws if the length of the list has
- * changed during iteration.
- */
-class MappedListIterator<S, T> implements Iterator<T> {
-  List<S> _list;
-  // TODO(ahe): Restore type when feature is implemented in dart2js
-  // checked mode. http://dartbug.com/7733
-  final /* _Transformation<S, T> */ _f;
-  final int _endIndex;
-  final int _length;
-  int _index;
-  T _current;
-
-  MappedListIterator(List<S> list, this._f, int start, this._endIndex)
-      : _list = list, _length = list.length, _index = start;
-
-  T get current => _current;
-
-  bool moveNext() {
-    if (_list.length != _length) {
-      throw new ConcurrentModificationError(_list);
-    }
-    if (_index >= _endIndex) {
-      _current = null;
-      return false;
-    }
-    _current = _f(_list[_index]);
-    _index++;
-    return true;
-  }
-}
 
 typedef bool _ElementPredicate<E>(E element);
 
@@ -969,8 +662,6 @@
 
   Iterable map(f(E element)) => const EmptyIterable();
 
-  Iterable mappedBy(f(E element)) => const EmptyIterable();
-
   reduce(var initialValue, combine(var previousValue, E element)) {
     return initialValue;
   }
diff --git a/sdk/lib/_collection_dev/list.dart b/sdk/lib/_collection_dev/list.dart
index 7af0fbb..fe698ec 100644
--- a/sdk/lib/_collection_dev/list.dart
+++ b/sdk/lib/_collection_dev/list.dart
@@ -97,27 +97,23 @@
     return new MappedIterable(this, f);
   }
 
-  List mappedBy(f(E element)) {
-    return new MappedList(this, f);
+  Iterable<E> take(int n) {
+    return new SubListIterable(this, 0, n);
   }
 
-  List<E> take(int n) {
-    return new ListView(this, 0, n);
+  Iterable<E> skip(int n) {
+    return new SubListIterable(this, n, null);
   }
 
-  List<E> skip(int n) {
-    return new ListView(this, n, null);
-  }
+  Iterable<E> get reversed => new ReversedListIterable(this);
 
   String toString() => ToString.collectionToString(this);
-
-  List<E> get reversed {
-    return new ReversedListView(this, 0, null);
-  }
 }
 
 /**
  * Abstract class implementing the non-length changing operations of [List].
+ *
+ * All modifications are performed using [[]=].
  */
 abstract class FixedLengthListBase<E> extends ListBase<E> {
   void operator[]=(int index, E value);
@@ -286,264 +282,22 @@
   }
 }
 
-/**
- * Iterates over a [List] in growing index order.
- */
-class ListIterator<E> implements Iterator<E> {
-  final List<E> _list;
-  final int _length;
-  int _position;
-  E _current;
-
-  ListIterator(List<E> list)
-      : _list = list, _position = -1, _length = list.length;
-
-  bool moveNext() {
-    if (_list.length != _length) {
-      throw new ConcurrentModificationError(_list);
-    }
-    int nextPosition = _position + 1;
-    if (nextPosition < _length) {
-      _position = nextPosition;
-      _current = _list[nextPosition];
-      return true;
-    }
-    _current = null;
-    return false;
-  }
-
-  E get current => _current;
-}
-
-class MappedList<S, T> extends UnmodifiableListBase<T> {
-  final List<S> _list;
-  // TODO(ahe): Restore type when feature is implemented in dart2js
-  // checked mode. http://dartbug.com/7733
-  final /* _Transformation<S, T> */ _f;
-
-  MappedList(this._list, T this._f(S element));
-
-  T operator[](int index) => _f(_list[index]);
-  int get length => _list.length;
-}
-
 /** An empty fixed-length list. */
 class EmptyList<E> extends FixedLengthListBase<E> {
   int get length => 0;
   E operator[](int index) { throw new RangeError.value(index); }
   void operator []=(int index, E value) { throw new RangeError.value(index); }
-  List<E> skip(int count) => this;
-  List<E> take(int count) => this;
-  List<E> get reversed => this;
+  Iterable<E> skip(int count) => const EmptyIterable();
+  Iterable<E> take(int count) => const EmptyIterable();
+  Iterable<E> get reversed => const EmptyIterable();
   void sort([int compare(E a, E b)]) {}
 }
 
-/**
- * A fixed-length view of a sub-range of another [List].
- *
- * The range is described by start and end points relative
- * to the other List's start or end.
- *
- * The range changes dynamically as the underlying list changes
- * its length.
- */
-abstract class SubListView<E> extends UnmodifiableListBase<E> {
-  final List<E> _list;
-  final int _start;
-  final int _end;
+class ReversedListIterable<E> extends ListIterable<E> {
+  Iterable<E> _source;
+  ReversedListIterable(this._source);
 
-  /**
-   * Create a sub-list view.
-   *
-   * Both [_start] and [_end] can be given as positions
-   * relative to the start of [_list] (a non-negative integer)
-   * or relative to the end of [_list] (a negative integer or
-   * null, with null being at the end of the list).
-   */
-  SubListView(this._list, this._start, this._end);
+  int get length => _source.length;
 
-  int _absoluteIndex(int relativeIndex) {
-    if (relativeIndex == null) return _list.length;
-    if (relativeIndex < 0) {
-      int result = _list.length + relativeIndex;
-      if (result < 0) return 0;
-      return result;
-    }
-    if (relativeIndex > _list.length) {
-      return _list.length;
-    }
-    return relativeIndex;
-  }
-
-  int get length {
-    int result = _absoluteIndex(_end) - _absoluteIndex(_start);
-    if (result >= 0) return result;
-    return 0;
-  }
-
-  _createListView(int start, int end) {
-    if (start == null) return new EmptyList<E>();
-    if (end != null) {
-      if (start < 0) {
-        if (end <= start) return new EmptyList<E>();
-      } else {
-        if (end >= 0 && end <= start) return new EmptyList<E>();
-      }
-    }
-    return new ListView(_list, start, end);
-  }
-
-  _createReversedListView(int start, int end) {
-    if (start == null) return new EmptyList<E>();
-    if (end != null) {
-      if (start < 0) {
-        if (end <= start) return new EmptyList<E>();
-      } else {
-        if (end >= 0 && end <= start) return new EmptyList<E>();
-      }
-    }
-    return new ReversedListView(_list, start, end);
-  }
-}
-
-
-/**
- * A fixed-length view of a sub-range of a [List].
- */
-class ListView<E> extends SubListView<E> {
-
-  ListView(List<E> list, int start, int end) : super(list, start, end);
-
-  E operator[](int index) {
-    int start = _absoluteIndex(_start);
-    int end = _absoluteIndex(_end);
-    int length = end - start;
-    if (index < 0 || index >= length) {
-      throw new RangeError.range(index, 0, length);
-    }
-    return _list[start + index];
-  }
-
-  List<E> skip(int count) {
-    if (count is! int || count < 0) {
-      throw new ArgumentError(count);
-    }
-    if (_start == null) {
-      return new EmptyList<E>();
-    }
-    int newStart = _start + count;
-    if (_start < 0 && newStart >= 0) {
-      return new EmptyList<E>();
-    }
-    return _createListView(newStart, _end);
-  }
-
-  List<E> take(int count) {
-    if (count is! int || count < 0) {
-      throw new ArgumentError(count);
-    }
-    if (_start == null) {
-      return new EmptyList<E>();
-    }
-    int newEnd = _start + count;
-    if (_start < 0 && newEnd >= 0) {
-      newEnd = null;
-    }
-    return _createListView(_start, newEnd);
-  }
-
-  List<E> get reversed => new ReversedListView(_list, _start, _end);
-}
-
-/**
- * Reversed view of a [List], or a slice of a list.
- *
- * The view is fixed-length and becomes invalid if the underlying
- * list changes its length below the slice used by this reversed list.
- *
- * Start index and end index can be either positive, negative or null.
- * Positive means an index relative to the start of the list,
- * negative means an index relative to the end of the list, and null
- * means at the end of the list (since there is no -0 integer).
- */
-class ReversedListView<E> extends SubListView<E> {
-
-  ReversedListView(List<E> list, int start, int end)
-      : super(list, start, end);
-
-  E operator[](int index) {
-    int start = _absoluteIndex(_start);
-    int end = _absoluteIndex(_end);
-    int length = end - start;
-    if (index < 0 || index >= length) {
-      throw new RangeError.range(index, 0, length);
-    }
-    return _list[end - index - 1];
-  }
-
-  List<E> skip(int count) {
-    if (count is! int || count < 0) {
-      throw new ArgumentError(count);
-    }
-    if (_end == null) {
-      return _createReversedListView(_start, -count);
-    }
-    int newEnd = _end - count;
-    if (_end >= 0 && newEnd < 0) {
-      return new EmptyList<E>();
-    }
-    return _createReversedListView(_start, newEnd);
-  }
-
-  List<E> take(int count) {
-    if (count is! int || count < 0) {
-      throw new ArgumentError(count);
-    }
-    int newStart;
-    if (_end == null) {
-      newStart = -count;
-    } else {
-      newStart = _end - count;
-      if (_end >= 0 && newStart < 0) {
-        return new EmptyList<E>();
-      }
-    }
-    return _createReversedListView(newStart, _end);
-  }
-
-  Iterator<E> get iterator => new ReverseListIterator<E>(
-      _list, _absoluteIndex(_start), _absoluteIndex(_end));
-
-  List<E> get reversed {
-    return new ListView(_list, _start, _end);
-  }
-}
-
-/**
- * An [Iterator] over a slice of a list that access elements in reverse order.
- */
-class ReverseListIterator<E> implements Iterator<E> {
-  final List<E> _list;
-  final int _start;
-  final int _originalLength;
-  int _index;
-  E _current;
-
-  ReverseListIterator(List<E> list, int start, int end)
-      : _list = list,
-        _start = start,
-        _index = end,
-        _originalLength = list.length;
-
-  bool moveNext() {
-    if (_list.length != _originalLength) {
-      throw new ConcurrentModificationError(_list);
-    }
-    if (_index <= _start) return false;
-    _index -= 1;
-    _current = _list[_index];
-    return true;
-  }
-
-  E get current => _current;
+  E elementAt(int index) => _source.elementAt(_source.length - 1 - index);
 }
diff --git a/sdk/lib/_internal/compiler/implementation/code_buffer.dart b/sdk/lib/_internal/compiler/implementation/code_buffer.dart
index c3465e8..795742d 100644
--- a/sdk/lib/_internal/compiler/implementation/code_buffer.dart
+++ b/sdk/lib/_internal/compiler/implementation/code_buffer.dart
@@ -20,11 +20,15 @@
     return buffer.isEmpty;
   }
 
+  CodeBuffer add(var object) {
+    write(object);
+    return this;
+  }
   /**
    * Converts [object] to a string and adds it to the buffer. If [object] is a
    * [CodeBuffer], adds its markers to [markers].
    */
-  CodeBuffer add(var object) {
+  CodeBuffer write(var object) {
     if (object is CodeBuffer) {
       return addBuffer(object);
     }
@@ -33,6 +37,17 @@
     return this;
   }
 
+  CodeBuffer writeAll(Iterable<Object> objects) {
+    for (var object in objects) {
+      write(object);
+    }
+    return this;
+  }
+
+  CodeBuffer writeln(var object) {
+    return write(object).write("\n");
+  }
+
   CodeBuffer addBuffer(CodeBuffer other) {
     if (other.markers.length > 0) {
       CodeBufferMarker firstMarker = other.markers[0];
@@ -46,17 +61,15 @@
       lastBufferOffset = buffer.length + other.lastBufferOffset;
     }
     buffer.add(other.getText());
-  }
-
-  CodeBuffer addAll(Iterable<Object> iterable) {
-    for (Object obj in iterable) {
-      add(obj);
-    }
     return this;
   }
 
-  CodeBuffer addCharCode(int charCode) {
-    return add(new String.fromCharCodes([charCode]));
+  CodeBuffer addAll(Iterable<Object> iterable) => writeAll(iterable);
+
+  CodeBuffer addCharCode(int charCode) => writeCharCode(charCode);
+
+  CodeBuffer writeCharCode(int charCode) {
+    return write(new String.fromCharCodes([charCode]));
   }
 
   CodeBuffer clear() {
diff --git a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
index 09e31da..b542b7a 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
@@ -244,7 +244,26 @@
 }
 
 patch class StringBuffer {
-  patch factory StringBuffer([Object content = ""]) {
-    return new JsStringBuffer(content);
+  String _contents = "";
+
+  patch StringBuffer([Object content = ""]) {
+    if (content is String) {
+      _contents = content;
+    } else {
+      write(content);
+    }
   }
+
+  patch int get length => _contents.length;
+
+  patch void write(Object obj) {
+    String str = obj is String ? obj : "$obj";
+    _contents = Primitives.stringConcatUnchecked(_contents, str);
+  }
+
+  patch void clear() {
+    _contents = "";
+  }
+
+  patch String toString() => _contents;
 }
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
index e33ae3f..1c1e492 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
@@ -92,10 +92,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(E element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   String join([String separator]) {
     if (separator == null) separator = "";
     var list = new List(this.length);
@@ -230,7 +226,7 @@
 
   bool every(bool f(E element)) => IterableMixinWorkaround.every(this, f);
 
-  List<E> get reversed => IterableMixinWorkaround.reversedList(this);
+  Iterable<E> get reversed => IterableMixinWorkaround.reversedList(this);
 
   void sort([int compare(E a, E b)]) {
     checkMutable(this, 'sort');
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index 844ee78..75724a7 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -347,6 +347,10 @@
     return _fromCharCodeApply(charCodes);
   }
 
+  static String stringConcatUnchecked(String string1, String string2) {
+    return JS('String', r'# + #', string1, string2);
+  }
+
   static String getTimeZoneName(receiver) {
     // When calling toString on a Date it will emit the timezone in parenthesis.
     // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)".
diff --git a/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
index 8ac1fa4..6e4dccf 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
@@ -202,33 +202,3 @@
 stringJoinUnchecked(array, separator) {
   return JS('String', r'#.join(#)', array, separator);
 }
-
-class JsStringBuffer implements StringBuffer {
-  String _contents;
-
-  JsStringBuffer(content)
-      : _contents = (content is String) ? content : '$content';
-
-  int get length => _contents.length;
-
-  bool get isEmpty => length == 0;
-
-  void add(Object obj) {
-    _contents = JS('String', '# + #', _contents,
-                   (obj is String) ? obj : '$obj');
-  }
-
-  void addAll(Iterable objects) {
-    for (Object obj in objects) add(obj);
-  }
-
-  void addCharCode(int charCode) {
-    add(new String.fromCharCodes([charCode]));
-  }
-
-  void clear() {
-    _contents = "";
-  }
-
-  String toString() => _contents;
-}
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 8df3d4e..85d73af 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -112,32 +112,35 @@
   }
 
   factory _FutureImpl.wait(Iterable<Future> futures) {
-    // TODO(ajohnsen): can we do better wrt. the generic type T?
-    if (futures.isEmpty) {
-      return new Future<List>.immediate(const []);
+    Completer completer;
+    // List collecting values from the futures.
+    // Set to null if an error occurs.
+    List values;
+    void handleError(error) {
+      if (values != null) {
+        values = null;
+        completer.completeError(error.error, error.stackTrace);
+      }
     }
-
-    Completer completer = new Completer<List>();
-    int remaining = futures.length;
-    List values = new List.fixedLength(futures.length);
-
     // As each future completes, put its value into the corresponding
     // position in the list of values.
-    int i = 0;
-    bool completed = false;
+    int remaining = 0;
     for (Future future in futures) {
-      int pos = i++;
-      future.then((Object value) {
+      int pos = remaining++;
+      future.catchError(handleError).then((Object value) {
+        if (values == null) return null;
         values[pos] = value;
-        if (--remaining == 0) {
+        remaining--;
+        if (remaining == 0) {
           completer.complete(values);
         }
-      }).catchError((error) {
-        if (!completed) completer.completeError(error.error, error.stackTrace);
-        completed = true;
       });
     }
-
+    if (remaining == 0) {
+      return new Future.immediate(const []);
+    }
+    values = new List.fixedLength(remaining);
+    completer = new Completer<List>();
     return completer.future;
   }
 
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index c713d9e..a026484 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -134,13 +134,6 @@
   }
 
   /**
-   * Deprecated alias for [map].
-   *
-   * @deprecated
-   */
-  Stream mappedBy(f(T element)) => map(f);
-
-  /**
    * Create a wrapper Stream that intercepts some errors from this stream.
    *
    * If this stream sends an error that matches [test], then it is intercepted
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index 81dd6da..b35a52f 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.dart
@@ -318,12 +318,7 @@
   }
 
   static Iterable mapList(List list, f(var element)) {
-    return new MappedListIterable(list, f, 0, null);
-  }
-
-  static List mappedByList(List list, f(var element)) {
-    // This is currently a List as well as an Iterable.
-    return new MappedList(list, f);
+    return new MappedListIterable(list, f);
   }
 
   static Iterable expand(Iterable iterable, Iterable f(var element)) {
@@ -333,7 +328,7 @@
   static Iterable takeList(List list, int n) {
     // The generic type is currently lost. It will be fixed with mixins.
     // This is currently a List as well as an Iterable.
-    return new ListView(list, 0, n);
+    return new SubListIterable(list, 0, n);
   }
 
   static Iterable takeWhile(Iterable iterable, bool test(var value)) {
@@ -344,7 +339,7 @@
   static Iterable skipList(List list, int n) {
     // The generic type is currently lost. It will be fixed with mixins.
     // This is currently a List as well as an Iterable.
-    return new ListView(list, n, null);
+    return new SubListIterable(list, n, null);
   }
 
   static Iterable skipWhile(Iterable iterable, bool test(var value)) {
@@ -352,8 +347,8 @@
     return new SkipWhileIterable(iterable, test);
   }
 
-  static List reversedList(List l) {
-    return new ReversedListView(l, 0, null);
+  static Iterable reversedList(List l) {
+    return new ReversedListIterable(l);
   }
 
   static void sortList(List l, int compare(a, b)) {
@@ -362,141 +357,21 @@
   }
 }
 
-/**
- * The [Collections] class implements static methods useful when
- * writing a class that implements [Collection] and the [iterator]
- * method.
- */
 class Collections {
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static bool contains(Iterable iterable, var element)
-      => IterableMixinWorkaround.contains(iterable, element);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static void forEach(Iterable iterable, void f(o)) {
-    IterableMixinWorkaround.forEach(iterable, f);
-  }
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static bool any(Iterable iterable, bool f(o))
-      => IterableMixinWorkaround.any(iterable, f);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static bool every(Iterable iterable, bool f(o))
-      => IterableMixinWorkaround.every(iterable, f);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static dynamic reduce(Iterable iterable,
-                        dynamic initialValue,
-                        dynamic combine(dynamic previousValue, element))
-      => IterableMixinWorkaround.reduce(iterable, initialValue, combine);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static bool isEmpty(Iterable iterable)
-      => IterableMixinWorkaround.isEmpty(iterable);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static dynamic first(Iterable iterable)
-      => IterableMixinWorkaround.first(iterable);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static dynamic last(Iterable iterable)
-      => IterableMixinWorkaround.last(iterable);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static dynamic min(Iterable iterable, [int compare(var a, var b)])
-      => IterableMixinWorkaround.min(iterable, compare);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static dynamic max(Iterable iterable, [int compare(var a, var b)])
-      => IterableMixinWorkaround.max(iterable, compare);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static dynamic single(Iterable iterable)
-      => IterableMixinWorkaround.single(iterable);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static dynamic firstMatching(Iterable iterable,
-                               bool test(dynamic value),
-                               dynamic orElse())
-      => IterableMixinWorkaround.firstMatching(iterable, test, orElse);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static dynamic lastMatching(Iterable iterable,
-                              bool test(dynamic value),
-                              dynamic orElse())
-      => IterableMixinWorkaround.lastMatching(iterable, test, orElse);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static dynamic lastMatchingInList(List list,
-                                    bool test(dynamic value),
-                                    dynamic orElse())
-      => IterableMixinWorkaround.lastMatchingInList(list, test, orElse);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static dynamic singleMatching(Iterable iterable, bool test(dynamic value))
-      => IterableMixinWorkaround.singleMatching(iterable, test);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static dynamic elementAt(Iterable iterable, int index)
-      => IterableMixinWorkaround.elementAt(iterable, index);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static String join(Iterable iterable, [String separator])
-      => IterableMixinWorkaround.join(iterable, separator);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static String joinList(List list, [String separator])
-      => IterableMixinWorkaround.joinList(list, separator);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static Iterable where(Iterable iterable, bool f(var element))
-      => IterableMixinWorkaround.where(iterable, f);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static List mappedByList(List list, f(var element))
-      => IterableMixinWorkaround.mappedByList(list, f);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static Iterable takeList(List list, int n)
-      => IterableMixinWorkaround.takeList(list, n);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static Iterable takeWhile(Iterable iterable, bool test(var value))
-      => IterableMixinWorkaround.takeWhile(iterable, test);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static Iterable skipList(List list, int n)
-      => IterableMixinWorkaround.skipList(list, n);
-
-  /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  @deprecated
-  static Iterable skipWhile(Iterable iterable, bool test(var value))
-      => IterableMixinWorkaround.skipWhile(iterable, test);
-
   static String collectionToString(Collection c)
       => ToString.collectionToString(c);
 }
+
+/**
+ * An unmodifiable [List] view of another List.
+ *
+ * The source of the elements may be a [List] or any [Iterable] with
+ * efficient [Iterable.length] and [Iterable.elementAt].
+ */
+class UnmodifiableListView<E> extends UnmodifiableListBase<E> {
+  Iterable<E> _source;
+  /** Create an unmodifiable list backed by [source]. */
+  UnmodifiableListView(Iterable<E> source) : _source = source;
+  int get length => _source.length;
+  E operator[](int index) => _source.elementAt(index);
+}
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index 1c307253..ca88387 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -35,5 +35,6 @@
 part "stopwatch.dart";
 part "string.dart";
 part "string_buffer.dart";
+part "string_sink.dart";
 part "strings.dart";
 part "type.dart";
diff --git a/sdk/lib/core/corelib_sources.gypi b/sdk/lib/core/corelib_sources.gypi
index a3d2202..529d725 100644
--- a/sdk/lib/core/corelib_sources.gypi
+++ b/sdk/lib/core/corelib_sources.gypi
@@ -33,6 +33,7 @@
     'string.dart',
     'strings.dart',
     'string_buffer.dart',
+    'string_sink.dart',
     'type.dart',
   ],
 }
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 56e96ef..618eeb8 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -51,12 +51,6 @@
   Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
 
   /**
-   * Deprecated alias for [map].
-   */
-  @deprecated
-  Iterable mappedBy(f(E element)) => map(f);
-
-  /**
    * Returns a lazy [Iterable] with all elements that satisfy the
    * predicate [f].
    *
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 10ba3e0..ecb5535 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -77,13 +77,9 @@
   void addAll(Iterable<E> iterable);
 
   /**
-   * Returns a reversed fixed-length view of this [List].
-   *
-   * The reversed list has elements in the opposite order of this list.
-   * It is backed by this list, but will stop working if this list
-   * becomes shorter than its current length.
+   * Returns an [Iterable] of the elements of this [List] in reverse order.
    */
-  List<E> get reversed;
+  Iterable<E> get reversed;
 
   /**
    * Sorts the list according to the order specified by the [compare] function.
diff --git a/sdk/lib/core/string_buffer.dart b/sdk/lib/core/string_buffer.dart
index d8b3935..cbfcd6e 100644
--- a/sdk/lib/core/string_buffer.dart
+++ b/sdk/lib/core/string_buffer.dart
@@ -9,29 +9,69 @@
  * efficiently. Only on a call to [toString] are the strings
  * concatenated to a single String.
  */
-abstract class StringBuffer {
+class StringBuffer implements StringSink {
 
   /// Creates the string buffer with an initial content.
-  external factory StringBuffer([Object content = ""]);
+  external StringBuffer([Object content = ""]);
 
   /// Returns the length of the buffer.
-  int get length;
+  external int get length;
 
-  // Returns whether the buffer is empty.
-  bool get isEmpty;
+  /// Returns whether the buffer is empty.
+  bool get isEmpty => length == 0;
 
-  /// Converts [obj] to a string and adds it to the buffer.
-  void add(Object obj);
+  /**
+   * Converts [obj] to a string and adds it to the buffer.
+   *
+   * *Deprecated*. Use [write] instead.
+   */
+  @deprecated
+  void add(Object obj) => write(obj);
+
+  external void write(Object obj);
+
+  void writeAll(Iterable objects) {
+    for (Object obj in objects) write(obj);
+  }
+
+  void writeln(Object obj) {
+    write(obj);
+    write("\n");
+  }
+
+  /**
+   * Adds the string representation of [charCode] to the buffer.
+   *
+   * *Deprecated* Use [writeCharCode] instead.
+   */
+  @deprecated
+  void addCharCode(int charCode) {
+    writeCharCode(charCode);
+  }
 
   /// Adds the string representation of [charCode] to the buffer.
-  void addCharCode(int charCode);
+  void writeCharCode(int charCode) {
+    write(new String.fromCharCode(charCode));
+  }
 
-  /// Adds all items in [objects] to the buffer.
-  void addAll(Iterable objects);
+  /**
+   * Adds all items in [objects] to the buffer.
+   *
+   * *Deprecated*. Use [writeAll] instead.
+   */
+  @deprecated
+  void addAll(Iterable objects) {
+    for (Object obj in objects) write(obj);
+  }
 
-  /// Clears the string buffer.
-  void clear();
+  /**
+   * Clears the string buffer.
+   *
+   * *Deprecated*.
+   */
+  @deprecated
+  external void clear();
 
   /// Returns the contents of buffer as a concatenated string.
-  String toString();
+  external String toString();
 }
diff --git a/sdk/lib/core/string_sink.dart b/sdk/lib/core/string_sink.dart
new file mode 100644
index 0000000..c2eff2d
--- /dev/null
+++ b/sdk/lib/core/string_sink.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart.core;
+
+abstract class StringSink {
+
+  /**
+   * Converts [obj] to a String by invoking [:toString:] and adds the result to
+   * this [StringSink].
+   */
+  void write(Object obj);
+
+  /**
+   * Iterates over the given [objects] and [write]s them in sequence.
+   */
+  void writeAll(Iterable objects);
+
+  /**
+   * Converts [obj] to a String by invoking [:toString:] and adds the result to
+   * this [StringSink]. Then adds a new line.
+   */
+  void writeln(Object obj);
+
+  /**
+   * Writes the [charCode] to this [StringSink].
+   *
+   * This method is equivalent to [:write(new String.fromCharCode(charCode)):].
+   */
+  void writeCharCode(int charCode);
+}
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 8688fea..3420aff 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -7197,9 +7197,6 @@
   Iterable map(f(DomMimeType element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(DomMimeType element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<DomMimeType> where(bool f(DomMimeType element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -7266,7 +7263,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<DomMimeType> get reversed {
+  Iterable<DomMimeType> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -7454,9 +7451,6 @@
   Iterable map(f(DomPlugin element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(DomPlugin element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<DomPlugin> where(bool f(DomPlugin element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -7523,7 +7517,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<DomPlugin> get reversed {
+  Iterable<DomPlugin> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -7818,9 +7812,6 @@
   Iterable map(f(String element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(String element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<String> where(bool f(String element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -7887,7 +7878,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<String> get reversed {
+  Iterable<String> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -8081,10 +8072,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(Element element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   Iterable<Element> where(bool f(Element element)) {
     return IterableMixinWorkaround.where(this, f);
   }
@@ -8165,7 +8152,7 @@
     }
   }
 
-  List<Element> get reversed {
+  Iterable<Element> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -8306,10 +8293,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(Element element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   Iterable<Element> where(bool f(Element element)) {
     return IterableMixinWorkaround.where(this, f);
   }
@@ -8399,7 +8382,7 @@
     throw new UnsupportedError('');
   }
 
-  List<Element> get reversed {
+  Iterable<Element> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -10660,9 +10643,6 @@
   Iterable map(f(File element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(File element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<File> where(bool f(File element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -10729,7 +10709,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<File> get reversed {
+  Iterable<File> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -11220,9 +11200,6 @@
   Iterable map(f(num element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(num element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<num> where(bool f(num element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -11289,7 +11266,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<num> get reversed {
+  Iterable<num> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -11439,9 +11416,6 @@
   Iterable map(f(num element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(num element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<num> where(bool f(num element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -11508,7 +11482,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<num> get reversed {
+  Iterable<num> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -11967,9 +11941,6 @@
   Iterable map(f(Node element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Node element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -12036,7 +12007,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed {
+  Iterable<Node> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -12177,9 +12148,6 @@
   Iterable map(f(Node element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Node element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -12246,7 +12214,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed {
+  Iterable<Node> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -14199,9 +14167,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -14268,7 +14233,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -14418,9 +14383,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -14487,7 +14449,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -14637,9 +14599,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -14706,7 +14665,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -17143,10 +17102,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(Node element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   Iterable<Node> where(bool f(Node element)) {
     return IterableMixinWorkaround.where(this, f);
   }
@@ -17198,7 +17153,7 @@
     return this[index];
   }
 
-  List<Node> get reversed {
+  Iterable<Node> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -17538,9 +17493,6 @@
   Iterable map(f(Node element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Node element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -17607,7 +17559,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed {
+  Iterable<Node> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -19643,16 +19595,14 @@
   // does not operate as a List.
   List<OptionElement> get options {
     var options = this.children.where((e) => e is OptionElement).toList();
-    // TODO(floitsch): find better way to create a read-only list view.
-    return options.take(options.length);
+    return new UnmodifiableListView<OptionElement>(options);
   }
 
   List<OptionElement> get selectedOptions {
     // IE does not change the selected flag for single-selection items.
     if (this.multiple) {
       var options = this.options.where((o) => o.selected).toList();
-      // TODO(floitsch): find better way to create a read-only list view.
-      return options.take(options.length);
+      return new UnmodifiableListView<OptionElement>(options);
     } else {
       return [this.options[this.selectedIndex]];
     }
@@ -19858,9 +19808,6 @@
   Iterable map(f(SourceBuffer element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(SourceBuffer element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<SourceBuffer> where(bool f(SourceBuffer element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -19927,7 +19874,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SourceBuffer> get reversed {
+  Iterable<SourceBuffer> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -20141,9 +20088,6 @@
   Iterable map(f(SpeechGrammar element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(SpeechGrammar element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<SpeechGrammar> where(bool f(SpeechGrammar element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -20210,7 +20154,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechGrammar> get reversed {
+  Iterable<SpeechGrammar> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -20712,9 +20656,6 @@
   Iterable map(f(Map element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Map element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Map> where(bool f(Map element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -20781,7 +20722,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Map> get reversed {
+  Iterable<Map> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -21798,9 +21739,6 @@
   Iterable map(f(TextTrackCue element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(TextTrackCue element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<TextTrackCue> where(bool f(TextTrackCue element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -21867,7 +21805,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<TextTrackCue> get reversed {
+  Iterable<TextTrackCue> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -22006,9 +21944,6 @@
   Iterable map(f(TextTrack element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(TextTrack element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<TextTrack> where(bool f(TextTrack element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -22075,7 +22010,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<TextTrack> get reversed {
+  Iterable<TextTrack> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -22421,9 +22356,6 @@
   Iterable map(f(Touch element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Touch element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Touch> where(bool f(Touch element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -22490,7 +22422,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Touch> get reversed {
+  Iterable<Touch> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -22870,9 +22802,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -22939,7 +22868,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -23089,9 +23018,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -23158,7 +23084,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -23308,9 +23234,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -23377,7 +23300,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -23524,9 +23447,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -23593,7 +23513,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -27243,9 +27163,6 @@
   Iterable map(f(ClientRect element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(ClientRect element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<ClientRect> where(bool f(ClientRect element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -27312,7 +27229,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<ClientRect> get reversed {
+  Iterable<ClientRect> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -27443,9 +27360,6 @@
   Iterable map(f(CssRule element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(CssRule element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<CssRule> where(bool f(CssRule element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -27512,7 +27426,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<CssRule> get reversed {
+  Iterable<CssRule> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -27643,9 +27557,6 @@
   Iterable map(f(CssValue element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(CssValue element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<CssValue> where(bool f(CssValue element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -27712,7 +27623,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<CssValue> get reversed {
+  Iterable<CssValue> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -27843,9 +27754,6 @@
   Iterable map(f(Entry element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Entry element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Entry> where(bool f(Entry element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -27912,7 +27820,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Entry> get reversed {
+  Iterable<Entry> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -28043,9 +27951,6 @@
   Iterable map(f(EntrySync element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(EntrySync element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<EntrySync> where(bool f(EntrySync element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -28112,7 +28017,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<EntrySync> get reversed {
+  Iterable<EntrySync> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -28243,9 +28148,6 @@
   Iterable map(f(Gamepad element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Gamepad element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Gamepad> where(bool f(Gamepad element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -28312,7 +28214,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Gamepad> get reversed {
+  Iterable<Gamepad> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -28506,9 +28408,6 @@
   Iterable map(f(MediaStream element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(MediaStream element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<MediaStream> where(bool f(MediaStream element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -28575,7 +28474,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<MediaStream> get reversed {
+  Iterable<MediaStream> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -28706,9 +28605,6 @@
   Iterable map(f(Node element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Node element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -28775,7 +28671,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed {
+  Iterable<Node> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -28930,9 +28826,6 @@
   Iterable map(f(SpeechInputResult element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(SpeechInputResult element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<SpeechInputResult> where(bool f(SpeechInputResult element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -28999,7 +28892,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechInputResult> get reversed {
+  Iterable<SpeechInputResult> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -29130,9 +29023,6 @@
   Iterable map(f(SpeechRecognitionResult element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(SpeechRecognitionResult element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<SpeechRecognitionResult> where(bool f(SpeechRecognitionResult element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -29199,7 +29089,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechRecognitionResult> get reversed {
+  Iterable<SpeechRecognitionResult> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -29330,9 +29220,6 @@
   Iterable map(f(StyleSheet element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(StyleSheet element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<StyleSheet> where(bool f(StyleSheet element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -29399,7 +29286,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<StyleSheet> get reversed {
+  Iterable<StyleSheet> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -29905,8 +29792,6 @@
 
   Iterable map(f(String element)) => readClasses().map(f);
 
-  Iterable mappedBy(f(String element)) => readClasses().mappedBy(f);
-
   Iterable<String> where(bool f(String element)) => readClasses().where(f);
 
   Iterable expand(Iterable f(String element)) => readClasses.expand(f);
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index ff46655..8a3b951 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -7898,9 +7898,6 @@
   Iterable map(f(DomMimeType element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(DomMimeType element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<DomMimeType> where(bool f(DomMimeType element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -7967,7 +7964,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<DomMimeType> get reversed {
+  Iterable<DomMimeType> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -8169,9 +8166,6 @@
   Iterable map(f(DomPlugin element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(DomPlugin element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<DomPlugin> where(bool f(DomPlugin element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -8238,7 +8232,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<DomPlugin> get reversed {
+  Iterable<DomPlugin> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -8558,9 +8552,6 @@
   Iterable map(f(String element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(String element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<String> where(bool f(String element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -8627,7 +8618,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<String> get reversed {
+  Iterable<String> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -8842,10 +8833,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(Element element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   Iterable<Element> where(bool f(Element element)) {
     return IterableMixinWorkaround.where(this, f);
   }
@@ -8926,7 +8913,7 @@
     }
   }
 
-  List<Element> get reversed {
+  Iterable<Element> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -9067,10 +9054,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(Element element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   Iterable<Element> where(bool f(Element element)) {
     return IterableMixinWorkaround.where(this, f);
   }
@@ -9160,7 +9143,7 @@
     throw new UnsupportedError('');
   }
 
-  List<Element> get reversed {
+  Iterable<Element> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -11396,9 +11379,6 @@
   Iterable map(f(File element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(File element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<File> where(bool f(File element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -11465,7 +11445,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<File> get reversed {
+  Iterable<File> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -12010,9 +11990,6 @@
   Iterable map(f(num element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(num element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<num> where(bool f(num element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -12079,7 +12056,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<num> get reversed {
+  Iterable<num> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -12248,9 +12225,6 @@
   Iterable map(f(num element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(num element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<num> where(bool f(num element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -12317,7 +12291,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<num> get reversed {
+  Iterable<num> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -12846,9 +12820,6 @@
   Iterable map(f(Node element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Node element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -12915,7 +12886,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed {
+  Iterable<Node> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -13058,9 +13029,6 @@
   Iterable map(f(Node element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Node element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -13127,7 +13095,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed {
+  Iterable<Node> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -15419,9 +15387,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -15488,7 +15453,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -15657,9 +15622,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -15726,7 +15688,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -15895,9 +15857,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -15964,7 +15923,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -18680,10 +18639,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(Node element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   Iterable<Node> where(bool f(Node element)) {
     return IterableMixinWorkaround.where(this, f);
   }
@@ -18735,7 +18690,7 @@
     return this[index];
   }
 
-  List<Node> get reversed {
+  Iterable<Node> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -19072,9 +19027,6 @@
   Iterable map(f(Node element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Node element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -19141,7 +19093,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed {
+  Iterable<Node> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -21456,16 +21408,14 @@
   // does not operate as a List.
   List<OptionElement> get options {
     var options = this.children.where((e) => e is OptionElement).toList();
-    // TODO(floitsch): find better way to create a read-only list view.
-    return options.take(options.length);
+    return new UnmodifiableListView<OptionElement>(options);
   }
 
   List<OptionElement> get selectedOptions {
     // IE does not change the selected flag for single-selection items.
     if (this.multiple) {
       var options = this.options.where((o) => o.selected).toList();
-      // TODO(floitsch): find better way to create a read-only list view.
-      return options.take(options.length);
+      return new UnmodifiableListView<OptionElement>(options);
     } else {
       return [this.options[this.selectedIndex]];
     }
@@ -21699,9 +21649,6 @@
   Iterable map(f(SourceBuffer element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(SourceBuffer element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<SourceBuffer> where(bool f(SourceBuffer element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -21768,7 +21715,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SourceBuffer> get reversed {
+  Iterable<SourceBuffer> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -22020,9 +21967,6 @@
   Iterable map(f(SpeechGrammar element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(SpeechGrammar element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<SpeechGrammar> where(bool f(SpeechGrammar element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -22089,7 +22033,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechGrammar> get reversed {
+  Iterable<SpeechGrammar> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -22678,9 +22622,6 @@
   Iterable map(f(Map element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Map element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Map> where(bool f(Map element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -22747,7 +22688,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Map> get reversed {
+  Iterable<Map> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -24000,9 +23941,6 @@
   Iterable map(f(TextTrackCue element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(TextTrackCue element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<TextTrackCue> where(bool f(TextTrackCue element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -24069,7 +24007,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<TextTrackCue> get reversed {
+  Iterable<TextTrackCue> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -24212,9 +24150,6 @@
   Iterable map(f(TextTrack element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(TextTrack element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<TextTrack> where(bool f(TextTrack element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -24281,7 +24216,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<TextTrack> get reversed {
+  Iterable<TextTrack> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -24631,9 +24566,6 @@
   Iterable map(f(Touch element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Touch element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Touch> where(bool f(Touch element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -24700,7 +24632,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Touch> get reversed {
+  Iterable<Touch> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -25125,9 +25057,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -25194,7 +25123,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -25363,9 +25292,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -25432,7 +25358,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -25601,9 +25527,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -25670,7 +25593,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -25837,9 +25760,6 @@
   Iterable map(f(int element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(int element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -25906,7 +25826,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed {
+  Iterable<int> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -29515,9 +29435,6 @@
   Iterable map(f(ClientRect element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(ClientRect element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<ClientRect> where(bool f(ClientRect element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -29584,7 +29501,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<ClientRect> get reversed {
+  Iterable<ClientRect> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -29719,9 +29636,6 @@
   Iterable map(f(CssRule element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(CssRule element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<CssRule> where(bool f(CssRule element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -29788,7 +29702,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<CssRule> get reversed {
+  Iterable<CssRule> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -29923,9 +29837,6 @@
   Iterable map(f(CssValue element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(CssValue element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<CssValue> where(bool f(CssValue element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -29992,7 +29903,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<CssValue> get reversed {
+  Iterable<CssValue> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -30270,9 +30181,6 @@
   Iterable map(f(Entry element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Entry element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Entry> where(bool f(Entry element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -30339,7 +30247,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Entry> get reversed {
+  Iterable<Entry> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -30474,9 +30382,6 @@
   Iterable map(f(EntrySync element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(EntrySync element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<EntrySync> where(bool f(EntrySync element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -30543,7 +30448,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<EntrySync> get reversed {
+  Iterable<EntrySync> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -30678,9 +30583,6 @@
   Iterable map(f(Gamepad element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Gamepad element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Gamepad> where(bool f(Gamepad element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -30747,7 +30649,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Gamepad> get reversed {
+  Iterable<Gamepad> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -30973,9 +30875,6 @@
   Iterable map(f(MediaStream element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(MediaStream element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<MediaStream> where(bool f(MediaStream element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -31042,7 +30941,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<MediaStream> get reversed {
+  Iterable<MediaStream> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -31177,9 +31076,6 @@
   Iterable map(f(Node element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Node element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -31246,7 +31142,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed {
+  Iterable<Node> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -31405,9 +31301,6 @@
   Iterable map(f(SpeechInputResult element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(SpeechInputResult element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<SpeechInputResult> where(bool f(SpeechInputResult element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -31474,7 +31367,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechInputResult> get reversed {
+  Iterable<SpeechInputResult> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -31609,9 +31502,6 @@
   Iterable map(f(SpeechRecognitionResult element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(SpeechRecognitionResult element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<SpeechRecognitionResult> where(bool f(SpeechRecognitionResult element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -31678,7 +31568,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechRecognitionResult> get reversed {
+  Iterable<SpeechRecognitionResult> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -31813,9 +31703,6 @@
   Iterable map(f(StyleSheet element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(StyleSheet element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<StyleSheet> where(bool f(StyleSheet element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -31882,7 +31769,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<StyleSheet> get reversed {
+  Iterable<StyleSheet> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -32390,8 +32277,6 @@
 
   Iterable map(f(String element)) => readClasses().map(f);
 
-  Iterable mappedBy(f(String element)) => readClasses().mappedBy(f);
-
   Iterable<String> where(bool f(String element)) => readClasses().where(f);
 
   Iterable expand(Iterable f(String element)) => readClasses.expand(f);
diff --git a/sdk/lib/html/html_common/filtered_element_list.dart b/sdk/lib/html/html_common/filtered_element_list.dart
index 330b0df..9337e6b 100644
--- a/sdk/lib/html/html_common/filtered_element_list.dart
+++ b/sdk/lib/html/html_common/filtered_element_list.dart
@@ -69,7 +69,7 @@
     return element is Element && _childNodes.contains(element);
   }
 
-  List<Element> get reversed => _filtered.reversed;
+  Iterable<Element> get reversed => _filtered.reversed;
 
   void sort([int compare(Element a, Element b)]) {
     throw new UnsupportedError('TODO(jacobr): should we impl?');
@@ -102,7 +102,6 @@
   }
 
   Iterable map(f(Element element)) => _filtered.map(f);
-  List mappedBy(f(Element element)) => _filtered.mappedBy(f);
   Iterable<Element> where(bool f(Element element)) => _filtered.where(f);
   Iterable expand(Iterable f(Element element)) => _filtered.expand(f);
 
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index 09a63ec..7543c2a 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -3082,9 +3082,6 @@
   Iterable map(f(Length element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Length element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Length> where(bool f(Length element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -3149,7 +3146,7 @@
 
   // clear() defined by IDL.
 
-  List<Length> get reversed {
+  Iterable<Length> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -3709,9 +3706,6 @@
   Iterable map(f(Number element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Number element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Number> where(bool f(Number element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -3776,7 +3770,7 @@
 
   // clear() defined by IDL.
 
-  List<Number> get reversed {
+  Iterable<Number> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -4612,9 +4606,6 @@
   Iterable map(f(PathSeg element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(PathSeg element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<PathSeg> where(bool f(PathSeg element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -4679,7 +4670,7 @@
 
   // clear() defined by IDL.
 
-  List<PathSeg> get reversed {
+  Iterable<PathSeg> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -5499,9 +5490,6 @@
   Iterable map(f(String element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(String element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<String> where(bool f(String element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -5566,7 +5554,7 @@
 
   // clear() defined by IDL.
 
-  List<String> get reversed {
+  Iterable<String> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -6665,9 +6653,6 @@
   Iterable map(f(Transform element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Transform element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Transform> where(bool f(Transform element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -6732,7 +6717,7 @@
 
   // clear() defined by IDL.
 
-  List<Transform> get reversed {
+  Iterable<Transform> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -7185,9 +7170,6 @@
   Iterable map(f(ElementInstance element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(ElementInstance element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<ElementInstance> where(bool f(ElementInstance element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -7254,7 +7236,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<ElementInstance> get reversed {
+  Iterable<ElementInstance> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index debc991..c0d430b 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -3346,9 +3346,6 @@
   Iterable map(f(Length element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Length element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Length> where(bool f(Length element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -3413,7 +3410,7 @@
 
   // clear() defined by IDL.
 
-  List<Length> get reversed {
+  Iterable<Length> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -4050,9 +4047,6 @@
   Iterable map(f(Number element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Number element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Number> where(bool f(Number element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -4117,7 +4111,7 @@
 
   // clear() defined by IDL.
 
-  List<Number> get reversed {
+  Iterable<Number> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -5230,9 +5224,6 @@
   Iterable map(f(PathSeg element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(PathSeg element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<PathSeg> where(bool f(PathSeg element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -5297,7 +5288,7 @@
 
   // clear() defined by IDL.
 
-  List<PathSeg> get reversed {
+  Iterable<PathSeg> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -6215,9 +6206,6 @@
   Iterable map(f(String element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(String element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<String> where(bool f(String element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -6282,7 +6270,7 @@
 
   // clear() defined by IDL.
 
-  List<String> get reversed {
+  Iterable<String> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -7470,9 +7458,6 @@
   Iterable map(f(Transform element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(Transform element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<Transform> where(bool f(Transform element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -7537,7 +7522,7 @@
 
   // clear() defined by IDL.
 
-  List<Transform> get reversed {
+  Iterable<Transform> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -8044,9 +8029,6 @@
   Iterable map(f(ElementInstance element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f(ElementInstance element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<ElementInstance> where(bool f(ElementInstance element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -8113,7 +8095,7 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<ElementInstance> get reversed {
+  Iterable<ElementInstance> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
diff --git a/tests/corelib/iterable_skip_test.dart b/tests/corelib/iterable_skip_test.dart
index fff6db7..b02e72a 100644
--- a/tests/corelib/iterable_skip_test.dart
+++ b/tests/corelib/iterable_skip_test.dart
@@ -13,7 +13,7 @@
   Set set2 = new Set();
 
   Iterable<int> skip0 = list1.skip(0);
-  Expect.isTrue(skip0 is List);
+  Expect.isTrue(skip0 is! List);
   Iterator<int> it = skip0.iterator;
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
@@ -26,8 +26,8 @@
   Expect.isNull(it.current);
 
   Iterable<int> skip1 = list1.skip(1);
-  Expect.isTrue(skip1 is List);
-  Expect.isTrue(skip1.skip(2).skip(1) is List);
+  Expect.isTrue(skip1 is! List);
+  Expect.isTrue(skip1.skip(2).skip(1) is! List);
   it = skip1.iterator;
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
@@ -38,8 +38,8 @@
   Expect.isNull(it.current);
 
   Iterable<int> skip2 = list1.skip(2);
-  Expect.isTrue(skip2 is List);
-  Expect.isTrue(skip2.skip(2).skip(1) is List);
+  Expect.isTrue(skip2 is! List);
+  Expect.isTrue(skip2.skip(2).skip(1) is! List);
   it = skip2.iterator;
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
@@ -48,16 +48,16 @@
   Expect.isNull(it.current);
 
   Iterable<int> skip3 = list1.skip(3);
-  Expect.isTrue(skip3 is List);
-  Expect.isTrue(skip3.skip(2).skip(1) is List);
+  Expect.isTrue(skip3 is! List);
+  Expect.isTrue(skip3.skip(2).skip(1) is! List);
   it = skip3.iterator;
   Expect.isNull(it.current);
   Expect.isFalse(it.moveNext());
   Expect.isNull(it.current);
 
   Iterable<int> skip4 = list1.skip(4);
-  Expect.isTrue(skip4 is List);
-  Expect.isTrue(skip4.skip(2).skip(1) is List);
+  Expect.isTrue(skip4 is! List);
+  Expect.isTrue(skip4.skip(2).skip(1) is! List);
   it = skip4.iterator;
   Expect.isNull(it.current);
   Expect.isFalse(it.moveNext());
@@ -102,8 +102,8 @@
   Expect.isNull(it.current);
 
   skip0 = list2.skip(0);
-  Expect.isTrue(skip0 is List);
-  Expect.isTrue(skip0.skip(2).skip(1) is List);
+  Expect.isTrue(skip0 is! List);
+  Expect.isTrue(skip0.skip(2).skip(1) is! List);
   it = skip0.iterator;
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
@@ -114,8 +114,8 @@
   Expect.isNull(it.current);
 
   skip1 = list2.skip(1);
-  Expect.isTrue(skip1 is List);
-  Expect.isTrue(skip1.skip(2).skip(1) is List);
+  Expect.isTrue(skip1 is! List);
+  Expect.isTrue(skip1.skip(2).skip(1) is! List);
   it = skip1.iterator;
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
@@ -124,32 +124,32 @@
   Expect.isNull(it.current);
 
   skip2 = list2.skip(2);
-  Expect.isTrue(skip2 is List);
-  Expect.isTrue(skip2.skip(2).skip(1) is List);
+  Expect.isTrue(skip2 is! List);
+  Expect.isTrue(skip2.skip(2).skip(1) is! List);
   it = skip2.iterator;
   Expect.isNull(it.current);
   Expect.isFalse(it.moveNext());
   Expect.isNull(it.current);
 
   skip3 = list2.skip(3);
-  Expect.isTrue(skip3 is List);
-  Expect.isTrue(skip3.skip(2).skip(1) is List);
+  Expect.isTrue(skip3 is! List);
+  Expect.isTrue(skip3.skip(2).skip(1) is! List);
   it = skip3.iterator;
   Expect.isNull(it.current);
   Expect.isFalse(it.moveNext());
   Expect.isNull(it.current);
 
   Iterable<String> skip02 = list3.skip(0);
-  Expect.isTrue(skip02 is List);
-  Expect.isTrue(skip02.skip(2).skip(1) is List);
+  Expect.isTrue(skip02 is! List);
+  Expect.isTrue(skip02.skip(2).skip(1) is! List);
   Iterator<String> it2 = skip02.iterator;
   Expect.isNull(it2.current);
   Expect.isFalse(it2.moveNext());
   Expect.isNull(it2.current);
 
   Iterable<String> skip12 = list3.skip(1);
-  Expect.isTrue(skip12 is List);
-  Expect.isTrue(skip12.skip(2).skip(1) is List);
+  Expect.isTrue(skip12 is! List);
+  Expect.isTrue(skip12.skip(2).skip(1) is! List);
   it2 = skip12.iterator;
   Expect.isNull(it2.current);
   Expect.isFalse(it2.moveNext());
@@ -224,4 +224,33 @@
   Expect.isNull(it.current);
   Expect.isFalse(it.moveNext());
   Expect.isNull(it.current);
+
+  testSkipTake(Iterable input, int skip, int take) {
+    List expected = [];
+    Iterator iter = input.iterator;
+    for (int i = 0; i < skip; i++) iter.moveNext();
+    for (int i = 0; i < take; i++) {
+      if (!iter.moveNext()) break;
+      expected.add(iter.current);
+    }
+    Expect.listEquals(expected, input.skip(skip).take(take).toList());
+  }
+
+  List longList = [1, 4, 5, 3, 8, 11, 12, 6, 9, 10, 13, 7, 2, 14, 15];
+  Set bigSet = longList.toSet();
+
+  for (Iterable collection in [longList, longList.reversed, bigSet]) {
+    testSkipTake(collection, 0, 0);
+    testSkipTake(collection, 0, 5);
+    testSkipTake(collection, 0, 15);
+    testSkipTake(collection, 0, 25);
+    testSkipTake(collection, 5, 0);
+    testSkipTake(collection, 5, 5);
+    testSkipTake(collection, 5, 10);
+    testSkipTake(collection, 5, 20);
+    testSkipTake(collection, 15, 0);
+    testSkipTake(collection, 15, 5);
+    testSkipTake(collection, 20, 0);
+    testSkipTake(collection, 20, 5);
+  }
 }
diff --git a/tests/corelib/iterable_take_test.dart b/tests/corelib/iterable_take_test.dart
index c775c52..3910769 100644
--- a/tests/corelib/iterable_take_test.dart
+++ b/tests/corelib/iterable_take_test.dart
@@ -13,16 +13,12 @@
   Set set2 = new Set();
 
   Iterable<int> take0 = list1.take(0);
-  Expect.isTrue(take0 is List);
-  Expect.isTrue(take0.take(2).take(1) is List);
   Iterator<int> it = take0.iterator;
   Expect.isNull(it.current);
   Expect.isFalse(it.moveNext());
   Expect.isNull(it.current);
 
   Iterable<int> take1 = list1.take(1);
-  Expect.isTrue(take1 is List);
-  Expect.isTrue(take1.take(2).take(1) is List);
   it = take1.iterator;
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
@@ -32,8 +28,6 @@
 
   Iterable<int> take2 = list1.take(2);
   it = take2.iterator;
-  Expect.isTrue(take2 is List);
-  Expect.isTrue(take2.take(2).take(1) is List);
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
   Expect.equals(1, it.current);
@@ -43,8 +37,6 @@
   Expect.isNull(it.current);
 
   Iterable<int> take3 = list1.take(3);
-  Expect.isTrue(take3 is List);
-  Expect.isTrue(take3.take(2).take(1) is List);
   it = take3.iterator;
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
@@ -57,8 +49,6 @@
   Expect.isNull(it.current);
 
   Iterable<int> take4 = list1.take(4);
-  Expect.isTrue(take4 is List);
-  Expect.isTrue(take4.take(2).take(1) is List);
   it = take4.iterator;
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
@@ -115,16 +105,12 @@
   Expect.isNull(it.current);
 
   take0 = list2.take(0);
-  Expect.isTrue(take0 is List);
-  Expect.isTrue(take0.take(2).take(1) is List);
   it = take0.iterator;
   Expect.isNull(it.current);
   Expect.isFalse(it.moveNext());
   Expect.isNull(it.current);
 
   take1 = list2.take(1);
-  Expect.isTrue(take1 is List);
-  Expect.isTrue(take1.take(2).take(1) is List);
   it = take1.iterator;
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
@@ -133,8 +119,6 @@
   Expect.isNull(it.current);
 
   take2 = list2.take(2);
-  Expect.isTrue(take2 is List);
-  Expect.isTrue(take2.take(2).take(1) is List);
   it = take2.iterator;
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
@@ -145,8 +129,6 @@
   Expect.isNull(it.current);
 
   take3 = list2.take(3);
-  Expect.isTrue(take3 is List);
-  Expect.isTrue(take3.take(2).take(1) is List);
   it = take3.iterator;
   Expect.isNull(it.current);
   Expect.isTrue(it.moveNext());
@@ -157,16 +139,12 @@
   Expect.isNull(it.current);
 
   Iterable<String> take02 = list3.take(0);
-  Expect.isTrue(take02 is List);
-  Expect.isTrue(take02.take(2).take(1) is List);
   Iterator<String> it2 = take02.iterator;
   Expect.isNull(it2.current);
   Expect.isFalse(it2.moveNext());
   Expect.isNull(it2.current);
 
   Iterable<String> take12 = list3.take(1);
-  Expect.isTrue(take12 is List);
-  Expect.isTrue(take12.take(2).take(1) is List);
   it2 = take12.iterator;
   Expect.isNull(it2.current);
   Expect.isFalse(it2.moveNext());
diff --git a/tests/corelib/list_map_test.dart b/tests/corelib/list_map_test.dart
new file mode 100644
index 0000000..92aa331
--- /dev/null
+++ b/tests/corelib/list_map_test.dart
@@ -0,0 +1,164 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+main() {
+  testOperations();
+}
+
+class ThrowMarker {
+  const ThrowMarker();
+  String toString() => "<<THROWS>>";
+}
+
+void testOperations() {
+  // Comparison lists.
+  List l = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+  List r = const [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
+  // Function that reverses l and r lists when used to map.
+  int rev(x) => 11 - x;
+  // A base list that starts out like l, but isn't const.
+  Iterable base = l.map((x) => x).toList();
+
+  Iterable reversed = l.map(rev);
+
+  Expect.listEquals(r, l.map(rev).toList());
+  Expect.listEquals(l, l.map(rev).map(rev).toList());
+  for (int i = 0; i < r.length; i++) {
+    Expect.equals(r[i], reversed.elementAt(i));
+  }
+  Expect.equals(4, base.indexOf(5));
+  Expect.equals(5, reversed.toList().indexOf(5));
+
+  // Reversed followed by combinations of skip and take.
+  List subr = [8, 7, 6, 5, 4, 3];
+  Expect.listEquals(subr, reversed.skip(2).take(6).toList());
+  Expect.listEquals(subr, reversed.take(8).skip(2).toList());
+  Expect.listEquals(subr,
+      reversed.toList().reversed.skip(2).take(6).toList().reversed.toList());
+  Expect.listEquals(subr,
+      reversed.toList().reversed.take(8).skip(2).toList().reversed.toList());
+  Expect.listEquals(subr,
+      reversed.take(8).toList().reversed.take(6).toList().reversed.toList());
+  Expect.listEquals(subr,
+      reversed.toList().reversed.take(8).toList().reversed.take(6).toList());
+  Expect.listEquals(subr,
+      reversed.toList().reversed.skip(2).toList().reversed.skip(2).toList());
+  Expect.listEquals(subr,
+      reversed.skip(2).toList().reversed.skip(2).toList().reversed.toList());
+
+
+  void testList(List list) {
+    var throws = const ThrowMarker();
+    List mappedList = new List(list.length);
+    for (int i = 0; i < list.length; i++) {
+      mappedList[i] = rev(list[i]);
+    }
+    Iterable reversed = list.map(rev);
+
+    void testEquals(v1, v2, path) {
+      if (v1 is Iterable) {
+        Iterator i1 = v1.iterator;
+        Iterator i2 = v2.iterator;
+        int index = 0;
+        while (i1.moveNext()) {
+          Expect.isTrue(i2.moveNext(),
+              "Too few actual values. Expected[$index] == ${i1.current}");
+          testEquals(i1.current, i2.current, "$path[$index]");
+          index++;
+        }
+        if (i2.moveNext()) {
+          Expect.fail(
+              "Too many actual values. Actual[$index] == ${i2.current}");
+        }
+      } else {
+        Expect.equals(v1, v2, path);
+      }
+    }
+
+    void testOp(operation(Iterable mappedList), name) {
+      var expect;
+      try {
+        expect = operation(mappedList);
+      } catch (e) {
+        expect = throws;
+      }
+      var actual;
+      try {
+        actual = operation(reversed);
+      } catch (e) {
+        actual = throws;
+      }
+      testEquals(expect, actual, "$name: $list");
+    }
+    testOp((i) => i.first, "first");
+    testOp((i) => i.last, "last");
+    testOp((i) => i.single, "single");
+    testOp((i) => i.firstMatching((n) => false), "firstMatching<false");
+    testOp((i) => i.firstMatching((n) => n < 10), "firstMatching<10");
+    testOp((i) => i.firstMatching((n) => n < 5), "firstMatching<5");
+    testOp((i) => i.firstMatching((n) => true), "firstMatching<true");
+    testOp((i) => i.lastMatching((n) => false), "lastMatching<false");
+    testOp((i) => i.lastMatching((n) => n < 5), "lastMatching<5");
+    testOp((i) => i.lastMatching((n) => n < 10), "lastMatching<10");
+    testOp((i) => i.lastMatching((n) => true), "lastMatching<true");
+    testOp((i) => i.singleMatching((n) => false), "singleMatching<false");
+    testOp((i) => i.singleMatching((n) => n < 5), "singelMatching<5");
+    testOp((i) => i.singleMatching((n) => n < 10), "singelMatching<10");
+    testOp((i) => i.singleMatching((n) => true), "singleMatching<true");
+    testOp((i) => i.contains(5), "contains(5)");
+    testOp((i) => i.contains(10), "contains(10)");
+    testOp((i) => i.any((n) => n < 5), "any<5");
+    testOp((i) => i.any((n) => n < 10), "any<10");
+    testOp((i) => i.every((n) => n < 5), "every<5");
+    testOp((i) => i.every((n) => n < 10), "every<10");
+    testOp((i) => i.max(), "max");
+    testOp((i) => i.min(), "min");
+    testOp((i) => i.reduce(0, (a, b) => a + b), "reduce-sum");
+    testOp((i) => i.join("-"), "join-");
+    testOp((i) => i.join(""), "join");
+    testOp((i) => i.join(), "join-null");
+    testOp((i) => i.map((n) => n * 2), "map*2");
+    testOp((i) => i.where((n) => n < 5), "where<5");
+    testOp((i) => i.where((n) => n < 10), "where<10");
+    testOp((i) => i.expand((n) => []), "expand[]");
+    testOp((i) => i.expand((n) => [n]), "expand[n]");
+    testOp((i) => i.expand((n) => [n, n]), "expand[n, n]");
+    testOp((i) => i.take(0), "take(0)");
+    testOp((i) => i.take(5), "take(5)");
+    testOp((i) => i.take(10), "take(10)");
+    testOp((i) => i.take(15), "take(15)");
+    testOp((i) => i.skip(0), "skip(0)");
+    testOp((i) => i.skip(5), "skip(5)");
+    testOp((i) => i.skip(10), "skip(10)");
+    testOp((i) => i.skip(15), "skip(15)");
+    testOp((i) => i.takeWhile((n) => false), "takeWhile(t)");
+    testOp((i) => i.takeWhile((n) => n < 5), "takeWhile(n<5)");
+    testOp((i) => i.takeWhile((n) => n > 5), "takeWhile(n>5)");
+    testOp((i) => i.takeWhile((n) => true), "takeWhile(f)");
+    testOp((i) => i.skipWhile((n) => false), "skipWhile(t)");
+    testOp((i) => i.skipWhile((n) => n < 5), "skipWhile(n<5)");
+    testOp((i) => i.skipWhile((n) => n > 5), "skipWhile(n>5)");
+    testOp((i) => i.skipWhile((n) => true), "skipWhile(f)");
+  }
+
+  // Combinations of lists with 0, 1 and more elements.
+  testList([]);
+  testList([0]);
+  testList([10]);
+  testList([0, 1]);
+  testList([0, 10]);
+  testList([10, 11]);
+  testList([0, 5, 10]);
+  testList([10, 5, 0]);
+  testList([0, 1, 2, 3]);
+  testList([3, 4, 5, 6]);
+  testList([10, 11, 12, 13]);
+  testList(l);
+  testList(r);
+  testList(base);
+
+  // Reverse const list.
+  Expect.listEquals(r, l.map(rev).toList());
+}
diff --git a/tests/corelib/list_reversed_test.dart b/tests/corelib/list_reversed_test.dart
index 03b99ce..d6c8484 100644
--- a/tests/corelib/list_reversed_test.dart
+++ b/tests/corelib/list_reversed_test.dart
@@ -7,6 +7,11 @@
   testOperations();
 }
 
+class ThrowMarker {
+  const ThrowMarker();
+  String toString() => "<<THROWS>>";
+}
+
 void testOperations() {
   // Comparison lists.
   List l = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
@@ -14,27 +19,118 @@
   // A base list that starts out like l.
   List base = l.toList();
   // A lazy reverse of base.
-  List reversed = base.reversed;
+  Iterable reversed = base.reversed;
 
-  Expect.listEquals(r, reversed);
-  Expect.listEquals(l, reversed.reversed);
+  Expect.listEquals(r, reversed.toList());
+  Expect.listEquals(l, reversed.toList().reversed.toList());
   for (int i = 0; i < r.length; i++) {
-    Expect.equals(r[i], reversed[i]);
+    Expect.equals(r[i], reversed.elementAt(i));
   }
   Expect.equals(4, base.indexOf(5));
-  Expect.equals(5, reversed.indexOf(5));
+  Expect.equals(5, reversed.toList().indexOf(5));
 
-  // Combinations of start and end relative to start/end of list.
+  // Reversed followed by combinations of skip and take.
   List subr = [8, 7, 6, 5, 4, 3];
-  Expect.listEquals(subr, reversed.skip(2).take(6));
-  Expect.listEquals(subr, reversed.take(8).skip(2));
-  Expect.listEquals(subr, reversed.reversed.skip(2).take(6).reversed);
-  Expect.listEquals(subr, reversed.reversed.take(8).skip(2).reversed);
-  Expect.listEquals(subr, reversed.take(8).reversed.take(6).reversed);
-  Expect.listEquals(subr, reversed.reversed.take(8).reversed.take(6));
-  Expect.listEquals(subr, reversed.reversed.skip(2).reversed.skip(2));
-  Expect.listEquals(subr, reversed.skip(2).reversed.skip(2).reversed);
+  Expect.listEquals(subr, reversed.skip(2).take(6).toList());
+  Expect.listEquals(subr, reversed.take(8).skip(2).toList());
+  Expect.listEquals(subr,
+      reversed.toList().reversed.skip(2).take(6).toList().reversed.toList());
+  Expect.listEquals(subr,
+      reversed.toList().reversed.take(8).skip(2).toList().reversed.toList());
+  Expect.listEquals(subr,
+      reversed.take(8).toList().reversed.take(6).toList().reversed.toList());
+  Expect.listEquals(subr,
+      reversed.toList().reversed.take(8).toList().reversed.take(6).toList());
+  Expect.listEquals(subr,
+      reversed.toList().reversed.skip(2).toList().reversed.skip(2).toList());
+  Expect.listEquals(subr,
+      reversed.skip(2).toList().reversed.skip(2).toList().reversed.toList());
+
+
+  void testList(List list) {
+    var throws = const ThrowMarker();
+    void testEquals(v1, v2, path) {
+      if (v1 is Iterable) {
+        Iterator i1 = v1.iterator;
+        Iterator i2 = v2.iterator;
+        int index = 0;
+        while (i1.moveNext()) {
+          Expect.isTrue(i2.moveNext(),
+              "Too few actual values. Expected[$index] == ${i1.current}");
+          testEquals(i1.current, i2.current, "$path[$index]");
+          index++;
+        }
+        if (i2.moveNext()) {
+          Expect.fail(
+              "Too many actual values. Actual[$index] == ${i2.current}");
+        }
+      } else {
+        Expect.equals(v1, v2, path);
+      }
+    }
+
+    void testOp(operation(Iterable reversedList), name) {
+      List reversedList = new List(list.length);
+      for (int i = 0; i < list.length; i++) {
+        reversedList[i] = list[list.length - 1 - i];
+      }
+      Iterable reversed = list.reversed;
+      var expect;
+      try {
+        expect = operation(reversedList);
+      } catch (e) {
+        expect = throws;
+      }
+      var actual;
+      try {
+        actual = operation(reversed);
+      } catch (e) {
+        actual = throws;
+      }
+      testEquals(expect, actual, "$name: $list");
+    }
+    testOp((i) => i.first, "first");
+    testOp((i) => i.last, "last");
+    testOp((i) => i.single, "single");
+    testOp((i) => i.firstMatching((n) => n < 5), "firstMatching<5");
+    testOp((i) => i.firstMatching((n) => n < 10), "firstMatching<10");
+    testOp((i) => i.lastMatching((n) => n < 5), "lastMatching<5");
+    testOp((i) => i.lastMatching((n) => n < 10), "lastMatching<10");
+    testOp((i) => i.singleMatching((n) => n < 5), "singelMatching<5");
+    testOp((i) => i.singleMatching((n) => n < 10), "singelMatching<10");
+    testOp((i) => i.contains(5), "contains(5)");
+    testOp((i) => i.contains(10), "contains(10)");
+    testOp((i) => i.any((n) => n < 5), "any<5");
+    testOp((i) => i.any((n) => n < 10), "any<10");
+    testOp((i) => i.every((n) => n < 5), "every<5");
+    testOp((i) => i.every((n) => n < 10), "every<10");
+    testOp((i) => i.max(), "max");
+    testOp((i) => i.min(), "min");
+    testOp((i) => i.reduce(0, (a, b) => a + b), "reduce-sum");
+    testOp((i) => i.join("-"), "join-");
+    testOp((i) => i.join(""), "join");
+    testOp((i) => i.join(), "join-null");
+    testOp((i) => i.map((n) => n * 2), "map*2");
+    testOp((i) => i.where((n) => n < 5), "where<5");
+    testOp((i) => i.where((n) => n < 10), "where<10");
+    testOp((i) => i.expand((n) => []), "expand[]");
+    testOp((i) => i.expand((n) => [n]), "expand[n]");
+    testOp((i) => i.expand((n) => [n, n]), "expand[n, n]");
+  }
+
+  // Combinations of lists with 0, 1 and more elements.
+  testList([]);
+  testList([0]);
+  testList([10]);
+  testList([0, 1]);
+  testList([0, 10]);
+  testList([10, 11]);
+  testList([0, 5, 10]);
+  testList([10, 5, 0]);
+  testList([0, 1, 2, 3]);
+  testList([3, 4, 5, 6]);
+  testList([10, 11, 12, 13]);
 
   // Reverse const list.
-  Expect.listEquals(r, l.reversed);
+  Expect.listEquals(r, l.reversed.toList());
 }
diff --git a/tests/html/element_classes_test.dart b/tests/html/element_classes_test.dart
index 89434fc..966e5eb 100644
--- a/tests/html/element_classes_test.dart
+++ b/tests/html/element_classes_test.dart
@@ -66,7 +66,7 @@
     expect(classes, unorderedEquals(['foo', 'bar', 'baz']));
   });
 
-  test('mappedBy', () {
+  test('map', () {
     expect(makeClassSet().map((c) => c.toUpperCase()).toList(),
         unorderedEquals(['FOO', 'BAR', 'BAZ']));
   });
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index 680face..a255c68 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -537,7 +537,7 @@
       expect(els[2], isHRElement);
     });
 
-    test('mappedBy', () {
+    test('map', () {
       var texts = getQueryAll().map((el) => el.text).toList();
       expect(texts, equals(['Dart!', 'Hello', '']));
     });
diff --git a/tests/html/streams_test.dart b/tests/html/streams_test.dart
index 8a46b65..3c3f5a2 100644
--- a/tests/html/streams_test.dart
+++ b/tests/html/streams_test.dart
@@ -191,7 +191,7 @@
     stream.where((_) => true).listen((_) {});
   });
 
-  test('mappedBy', () {
+  test('map', () {
     stream.map((_) => null).listen((_) {});
   });
 
diff --git a/tests/lib/async/stream_controller_async_test.dart b/tests/lib/async/stream_controller_async_test.dart
index 79b8568..36278bd 100644
--- a/tests/lib/async/stream_controller_async_test.dart
+++ b/tests/lib/async/stream_controller_async_test.dart
@@ -439,7 +439,7 @@
   }
 
   testStream("where", (s, act) => s.where(act));
-  testStream("mappedBy", (s, act) => s.map(act));
+  testStream("map", (s, act) => s.map(act));
   testStream("expand", (s, act) => s.expand(act));
   testStream("where", (s, act) => s.where(act));
   testStreamError("handleError", (s, act) => s.handleError(act));
diff --git a/tools/VERSION b/tools/VERSION
index 8b85f04..c411d7b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 3
 BUILD 7
-PATCH 3
+PATCH 4
diff --git a/tools/dom/src/CssClassSet.dart b/tools/dom/src/CssClassSet.dart
index d018108..72fdc7e 100644
--- a/tools/dom/src/CssClassSet.dart
+++ b/tools/dom/src/CssClassSet.dart
@@ -46,8 +46,6 @@
 
   Iterable map(f(String element)) => readClasses().map(f);
 
-  Iterable mappedBy(f(String element)) => readClasses().mappedBy(f);
-
   Iterable<String> where(bool f(String element)) => readClasses().where(f);
 
   Iterable expand(Iterable f(String element)) => readClasses.expand(f);
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 791b1ab..605731c 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -65,10 +65,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(Element element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   Iterable<Element> where(bool f(Element element)) {
     return IterableMixinWorkaround.where(this, f);
   }
@@ -149,7 +145,7 @@
     }
   }
 
-  List<Element> get reversed {
+  Iterable<Element> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
@@ -290,10 +286,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(Element element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   Iterable<Element> where(bool f(Element element)) {
     return IterableMixinWorkaround.where(this, f);
   }
@@ -383,7 +375,7 @@
     throw new UnsupportedError('');
   }
 
-  List<Element> get reversed {
+  Iterable<Element> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
diff --git a/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
index 0f378ab..3417187 100644
--- a/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
@@ -11,16 +11,14 @@
   // does not operate as a List.
   List<OptionElement> get options {
     var options = this.children.where((e) => e is OptionElement).toList();
-    // TODO(floitsch): find better way to create a read-only list view.
-    return options.take(options.length);
+    return new UnmodifiableListView<OptionElement>(options);
   }
 
   List<OptionElement> get selectedOptions {
     // IE does not change the selected flag for single-selection items.
     if (this.multiple) {
       var options = this.options.where((o) => o.selected).toList();
-      // TODO(floitsch): find better way to create a read-only list view.
-      return options.take(options.length);
+      return new UnmodifiableListView<OptionElement>(options);
     } else {
       return [this.options[this.selectedIndex]];
     }
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index ceeb922..aee4497 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -145,10 +145,6 @@
     return IterableMixinWorkaround.mapList(this, f);
   }
 
-  List mappedBy(f(Node element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
-  }
-
   Iterable<Node> where(bool f(Node element)) {
     return IterableMixinWorkaround.where(this, f);
   }
@@ -200,7 +196,7 @@
     return this[index];
   }
 
-  List<Node> get reversed {
+  Iterable<Node> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
diff --git a/tools/dom/templates/immutable_list_mixin.darttemplate b/tools/dom/templates/immutable_list_mixin.darttemplate
index 2c8bf68..850c2f8 100644
--- a/tools/dom/templates/immutable_list_mixin.darttemplate
+++ b/tools/dom/templates/immutable_list_mixin.darttemplate
@@ -32,9 +32,6 @@
   Iterable map(f($E element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  List mappedBy(f($E element)) =>
-      IterableMixinWorkaround.mappedByList(this, f);
-
   Iterable<$E> where(bool f($E element)) =>
       IterableMixinWorkaround.where(this, f);
 
@@ -107,7 +104,7 @@
   // clear() defined by IDL.
 $endif
 
-  List<$E> get reversed {
+  Iterable<$E> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
diff --git a/utils/pub/entrypoint.dart b/utils/pub/entrypoint.dart
index 054541d..7de7c2c 100644
--- a/utils/pub/entrypoint.dart
+++ b/utils/pub/entrypoint.dart
@@ -134,7 +134,7 @@
       return Future.wait(packageVersions.map((id) {
         if (id.isRoot) return new Future.immediate(id);
         return install(id);
-      }));
+      }).toList());
     }).then(_saveLockFile)
       .then(_installSelfReference)
       .then(_linkSecondaryPackageDirs);
@@ -267,7 +267,7 @@
             if (!dirExists(file)) return;
             return _linkSecondaryPackageDir(file);
           });
-        }));
+        }).toList());
       });
     });
   }
@@ -287,7 +287,7 @@
           fileAndSubfiles.addAll(subfiles);
           return fileAndSubfiles;
         });
-      }));
+      }).toList());
     }).then(flatten);
   }
 
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart
index a058e48..f7589da 100644
--- a/utils/pub/utils.dart
+++ b/utils/pub/utils.dart
@@ -274,13 +274,13 @@
 /// Like [Iterable.where], but allows [test] to return [Future]s and uses the
 /// results of those [Future]s as the test.
 Future<Iterable> futureWhere(Iterable iter, test(value)) {
-  return Future.wait(iter.mappedBy((e) {
+  return Future.wait(iter.map((e) {
     var result = test(e);
     if (result is! Future) result = new Future.immediate(result);
     return result.then((result) => new Pair(e, result));
   }))
       .then((pairs) => pairs.where((pair) => pair.last))
-      .then((pairs) => pairs.mappedBy((pair) => pair.first));
+      .then((pairs) => pairs.map((pair) => pair.first));
 }
 
 // TODO(nweiz): unify the following functions with the utility functions in
diff --git a/utils/template/utils.dart b/utils/template/utils.dart
index c9b8042..ca36fc6 100644
--- a/utils/template/utils.dart
+++ b/utils/template/utils.dart
@@ -7,7 +7,7 @@
 
 // TODO(jmesserly): we might want a version of this that return an iterable,
 // however JS, Python and Ruby versions are all eager.
-List mappedBy(Iterable source, mapper(source)) {
+List map(Iterable source, mapper(source)) {
   List result = new List();
   if (source is List) {
     List list = source; // TODO: shouldn't need this