diff --git a/CHANGELOG.md b/CHANGELOG.md
index d6f9d8f..b41cd9a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,21 @@
+## 0.18.0
+
+* Refactor and deprecate `ObservableList`-specific API
+    * `ObservableList.applyChangeRecords`
+    * `ObservableList.calculateChangeRecords`
+    * `ObservableList.withLength`
+    * `ObservableList.deliverListChanges`
+    * `ObservableList.discardListChanges`
+    * `ObservableList.hasListChanges`
+    * `ObservableList.listChanges`
+    * `ObservableList.notifyListChange`
+* Potentially breaking: `ObservableList` may no longer be extended
+
+It is also considered deprecated to be notified of `length`, `isEmpty`
+and `isNotEmpty` `PropertyChangeRecord`s on `ObservableList` - in a
+future release `ObservableList.changes` will be
+`Stream<List<ListChangeRecord>>`.
+
 ## 0.17.0+1
 
 * Revert `PropertyChangeMixin`, which does not work in dart2js
diff --git a/lib/observable.dart b/lib/observable.dart
index 516ff70..a2d1fca 100644
--- a/lib/observable.dart
+++ b/lib/observable.dart
@@ -5,10 +5,10 @@
 library observable;
 
 export 'src/change_notifier.dart' show ChangeNotifier, PropertyChangeNotifier;
+export 'src/collections.dart' show ObservableList;
 export 'src/differs.dart' show Differ, EqualityDiffer, ListDiffer, MapDiffer;
 export 'src/records.dart'
     show ChangeRecord, ListChangeRecord, MapChangeRecord, PropertyChangeRecord;
 export 'src/observable.dart';
-export 'src/observable_list.dart';
 export 'src/observable_map.dart';
 export 'src/to_observable.dart';
diff --git a/lib/src/change_notifier.dart b/lib/src/change_notifier.dart
index f60eb16..775df10 100644
--- a/lib/src/change_notifier.dart
+++ b/lib/src/change_notifier.dart
@@ -49,7 +49,6 @@
   ///
   /// Returns `true` if changes were emitted.
   @override
-  @protected
   @mustCallSuper
   bool deliverChanges() {
     List<ChangeRecord> changes;
diff --git a/lib/src/collections.dart b/lib/src/collections.dart
new file mode 100644
index 0000000..7aaff1d
--- /dev/null
+++ b/lib/src/collections.dart
@@ -0,0 +1 @@
+export 'collections/observable_list.dart';
diff --git a/lib/src/collections/observable_list.dart b/lib/src/collections/observable_list.dart
new file mode 100644
index 0000000..5cc643a
--- /dev/null
+++ b/lib/src/collections/observable_list.dart
@@ -0,0 +1,438 @@
+import 'dart:async';
+
+import 'package:collection/collection.dart';
+import 'package:observable/observable.dart';
+import 'package:observable/src/differs.dart';
+
+/// A [List] that broadcasts [changes] to subscribers for efficient mutations.
+///
+/// When client code expects a read heavy/write light workload, it is often more
+/// efficient to notify _when_ something has changed, instead of constantly
+/// diffing lists to find a single change (like an inserted record). You may
+/// accept an observable list to be notified of mutations:
+///     set names(List<String> names) {
+///       clearAndWrite(names);
+///       if (names is ObservableList<String>) {
+///         names.listChanges.listen(smallIncrementalUpdate);
+///       }
+///     }
+///
+/// *See [ListDiffer] to manually diff two lists instead*
+abstract class ObservableList<E> implements List<E>, Observable {
+  /// Applies [changes] to [previous] based on the [current] values.
+  ///
+  /// ## Deprecated
+  ///
+  /// If you need this functionality, copy it into your own library. The only
+  /// known usage is in `package:template_binding` - it will be upgraded before
+  /// removing this method.
+  @Deprecated('Use ListChangeRecord#apply instead')
+  static void applyChangeRecords/*<T>*/(
+    List/*<T>*/ previous,
+    List/*<T>*/ current,
+    List<ListChangeRecord/*<T>*/ > changes,
+  ) {
+    if (identical(previous, current)) {
+      throw new ArgumentError("Can't use same list for previous and current");
+    }
+    for (final change in changes) {
+      change.apply(previous);
+    }
+  }
+
+  /// Calculates change records between [previous] and [current].
+  ///
+  /// ## Deprecated
+  ///
+  /// This was moved into `ListDiffer.diff`.
+  @Deprecated('Use `ListDiffer.diff` instead')
+  static List<ListChangeRecord/*<T>*/ > calculateChangeRecords/*<T>*/(
+    List/*<T>*/ previous,
+    List/*<T>*/ current,
+  ) {
+    return const ListDiffer/*<T>*/().diff(previous, current);
+  }
+
+  /// Creates an observable list of the given [length].
+  factory ObservableList([int length]) {
+    final list = length != null ? new List<E>(length) : <E>[];
+    return new _ObservableDelegatingList(list);
+  }
+
+  /// Create a new observable list.
+  ///
+  /// Optionally define a [list] to use as a backing store.
+  factory ObservableList.delegate([List<E> list]) {
+    return new _ObservableDelegatingList(list ?? <E>[]);
+  }
+
+  /// Create a new observable list from [elements].
+  factory ObservableList.from(Iterable<E> elements) {
+    return new _ObservableDelegatingList(elements.toList());
+  }
+
+  /// Creates a new observable list of the given [length].
+  @Deprecated('Use the default constructor')
+  factory ObservableList.withLength(int length) {
+    return new ObservableList<E>(length);
+  }
+
+  @Deprecated('No longer supported. Just use deliverChanges')
+  bool deliverListChanges();
+
+  @Deprecated('No longer supported')
+  void discardListChanges();
+
+  @Deprecated('The `changes` stream emits ListChangeRecord now')
+  bool get hasListObservers;
+
+  /// A stream of summarized list changes, delivered asynchronously.
+  @Deprecated(''
+      'The `changes` stream will soon only emit ListChangeRecord; '
+      'either continue to use this getter until removed, or use the changes '
+      'stream with a `Stream.where` guard')
+  Stream<List<ListChangeRecord<E>>> get listChanges;
+
+  @Deprecated('Should no longer be used external from ObservableList')
+  void notifyListChange(
+    int index, {
+    List<E> removed: const [],
+    int addedCount: 0,
+  });
+}
+
+class _ObservableDelegatingList<E> extends DelegatingList<E>
+    implements ObservableList<E> {
+  final _listChanges = new ChangeNotifier<ListChangeRecord<E>>();
+  final _propChanges = new ChangeNotifier<PropertyChangeRecord>();
+
+  StreamController<List<ChangeRecord>> _allChanges;
+
+  _ObservableDelegatingList(List<E> store) : super(store);
+
+  // Observable
+
+  @override
+  Stream<List<ChangeRecord>> get changes {
+    if (_allChanges == null) {
+      StreamSubscription listSub;
+      StreamSubscription propSub;
+      _allChanges = new StreamController<List<ChangeRecord>>.broadcast(
+          sync: true,
+          onListen: () {
+            listSub = listChanges.listen(_allChanges.add);
+            propSub = _propChanges.changes.listen(_allChanges.add);
+          },
+          onCancel: () {
+            listSub.cancel();
+            propSub.cancel();
+          });
+    }
+    return _allChanges.stream;
+  }
+
+  // ChangeNotifier (deprecated for ObservableList)
+
+  @override
+  bool deliverChanges() {
+    final deliveredListChanges = _listChanges.deliverChanges();
+    final deliveredPropChanges = _propChanges.deliverChanges();
+    return deliveredListChanges || deliveredPropChanges;
+  }
+
+  @override
+  void discardListChanges() {
+    // This used to do something, but now we just make it a no-op.
+  }
+
+  @override
+  bool get hasObservers {
+    return _listChanges.hasObservers || _propChanges.hasObservers;
+  }
+
+  @override
+  void notifyChange([ChangeRecord change]) {
+    if (change is ListChangeRecord<E>) {
+      _listChanges.notifyChange(change);
+    } else if (change is PropertyChangeRecord) {
+      _propChanges.notifyChange(change);
+    }
+  }
+
+  @override
+  /*=T*/ notifyPropertyChange/*<T>*/(
+    Symbol field,
+    /*=T*/
+    oldValue,
+    /*=T*/
+    newValue,
+  ) {
+    if (oldValue != newValue) {
+      _propChanges.notifyChange(
+        new PropertyChangeRecord/*<T>*/(this, field, oldValue, newValue),
+      );
+    }
+    return newValue;
+  }
+
+  @override
+  void observed() {}
+
+  @override
+  void unobserved() {}
+
+  // ObservableList (deprecated)
+
+  @override
+  bool deliverListChanges() => _listChanges.deliverChanges();
+
+  @override
+  bool get hasListObservers => _listChanges.hasObservers;
+
+  @override
+  Stream<List<ListChangeRecord<E>>> get listChanges {
+    return _listChanges.changes.map((r) => projectListSplices(this, r));
+  }
+
+  @override
+  void notifyListChange(
+    int index, {
+    List<E> removed: const [],
+    int addedCount: 0,
+  }) {
+    _listChanges.notifyChange(new ListChangeRecord<E>(
+      this,
+      index,
+      removed: removed,
+      addedCount: addedCount,
+    ));
+  }
+
+  void _notifyChangeLength(int oldLength, int newLength) {
+    notifyPropertyChange(#length, oldLength, newLength);
+    notifyPropertyChange(#isEmpty, oldLength == 0, newLength == 0);
+    notifyPropertyChange(#isNotEmpty, oldLength != 0, newLength != 0);
+  }
+
+  // List
+
+  @override
+  operator []=(int index, E newValue) {
+    final oldValue = this[index];
+    if (hasObservers && oldValue != newValue) {
+      notifyListChange(index, removed: [oldValue], addedCount: 1);
+    }
+    super[index] = newValue;
+  }
+
+  @override
+  void add(E value) {
+    if (hasObservers) {
+      _notifyChangeLength(length, length + 1);
+      notifyListChange(length, addedCount: 1);
+    }
+    super.add(value);
+  }
+
+  @override
+  void addAll(Iterable<E> values) {
+    final oldLength = this.length;
+    super.addAll(values);
+    final newLength = this.length;
+    final addedCount = newLength - oldLength;
+    if (hasObservers && addedCount > 0) {
+      notifyListChange(oldLength, addedCount: addedCount);
+      _notifyChangeLength(oldLength, newLength);
+    }
+  }
+
+  @override
+  void clear() {
+    if (hasObservers) {
+      notifyListChange(0, removed: toList());
+      _notifyChangeLength(length, 0);
+    }
+    super.clear();
+  }
+
+  @override
+  void fillRange(int start, int end, [E value]) {
+    if (hasObservers) {
+      notifyListChange(
+        start,
+        addedCount: end - start,
+        removed: getRange(start, end).toList(),
+      );
+    }
+    super.fillRange(start, end, value);
+  }
+
+  @override
+  void insert(int index, E element) {
+    super.insert(index, element);
+    if (hasObservers) {
+      notifyListChange(index, addedCount: 1);
+      _notifyChangeLength(length - 1, length);
+    }
+  }
+
+  @override
+  void insertAll(int index, Iterable<E> values) {
+    final oldLength = this.length;
+    super.insertAll(index, values);
+    final newLength = this.length;
+    final addedCount = newLength - oldLength;
+    if (hasObservers && addedCount > 0) {
+      notifyListChange(index, addedCount: addedCount);
+      _notifyChangeLength(oldLength, newLength);
+    }
+  }
+
+  @override
+  set length(int newLength) {
+    final currentLength = this.length;
+    if (currentLength == newLength) {
+      return;
+    }
+    if (hasObservers) {
+      if (newLength < currentLength) {
+        notifyListChange(
+          newLength,
+          removed: getRange(newLength, currentLength).toList(),
+        );
+      } else {
+        notifyListChange(currentLength, addedCount: newLength - currentLength);
+      }
+    }
+    super.length = newLength;
+    if (hasObservers) {
+      _notifyChangeLength(currentLength, newLength);
+    }
+  }
+
+  @override
+  bool remove(Object element) {
+    if (!hasObservers) {
+      return super.remove(element);
+    }
+    for (var i = 0; i < this.length; i++) {
+      if (this[i] == element) {
+        removeAt(i);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  E removeAt(int index) {
+    if (hasObservers) {
+      final element = this[index];
+      notifyListChange(index, removed: [element]);
+      _notifyChangeLength(length, length - 1);
+    }
+    return super.removeAt(index);
+  }
+
+  @override
+  E removeLast() {
+    final element = super.removeLast();
+    if (hasObservers) {
+      notifyListChange(length, removed: [element]);
+      _notifyChangeLength(length + 1, length);
+    }
+    return element;
+  }
+
+  @override
+  void removeRange(int start, int end) {
+    final rangeLength = end - start;
+    if (hasObservers && rangeLength > 0) {
+      final removed = getRange(start, end).toList();
+      notifyListChange(start, removed: removed);
+      _notifyChangeLength(length, length - removed.length);
+    }
+    super.removeRange(start, end);
+  }
+
+  @override
+  void removeWhere(bool test(E element)) {
+    // We have to re-implement this if we have observers.
+    if (!hasObservers) return super.removeWhere(test);
+
+    // Produce as few change records as possible - if we have multiple removals
+    // in a sequence we want to produce a single record instead of a record for
+    // every element removed.
+    int firstRemovalIndex;
+
+    for (var i = 0; i < length; i++) {
+      var element = this[i];
+      if (test(element)) {
+        if (firstRemovalIndex == null) {
+          // This is the first item we've removed for this sequence.
+          firstRemovalIndex = i;
+        }
+      } else if (firstRemovalIndex != null) {
+        // We have a previous sequence of removals, but are not removing more.
+        removeRange(firstRemovalIndex, i--);
+        firstRemovalIndex = null;
+      }
+    }
+
+    // We have have a pending removal that was never finished.
+    if (firstRemovalIndex != null) {
+      removeRange(firstRemovalIndex, length);
+    }
+  }
+
+  @override
+  void replaceRange(int start, int end, Iterable<E> newContents) {
+    // This could be optimized not to emit two change records but would require
+    // code duplication with these methods. Since this is not used extremely
+    // often in my experience OK to just defer to these methods.
+    removeRange(start, end);
+    insertAll(start, newContents);
+  }
+
+  @override
+  void retainWhere(bool test(E element)) {
+    // This should be functionally the opposite of removeWhere.
+    removeWhere((E element) => !test(element));
+  }
+
+  @override
+  void setAll(int index, Iterable<E> elements) {
+    if (!hasObservers) {
+      super.setAll(index, elements);
+      return;
+    }
+    // Manual invocation of this method is required to get nicer change events.
+    var i = index;
+    final removed = <E>[];
+    for (var e in elements) {
+      removed.add(this[i]);
+      super[i++] = e;
+    }
+    if (removed.isNotEmpty) {
+      notifyListChange(index, removed: removed, addedCount: removed.length);
+    }
+  }
+
+  @override
+  void setRange(int start, int end, Iterable<E> elements, [int skipCount = 0]) {
+    if (!hasObservers) {
+      super.setRange(start, end, elements, skipCount);
+      return;
+    }
+    final iterator = elements.skip(skipCount).iterator..moveNext();
+    final removed = <E>[];
+    for (var i = start; i < end; i++) {
+      removed.add(super[i]);
+      super[i] = iterator.current;
+      iterator.moveNext();
+    }
+    if (removed.isNotEmpty) {
+      notifyListChange(start, removed: removed, addedCount: removed.length);
+    }
+  }
+}
diff --git a/lib/src/observable_list.dart b/lib/src/observable_list.dart
deleted file mode 100644
index 1618ce6..0000000
--- a/lib/src/observable_list.dart
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright (c) 2016, 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.
-
-library observable.src.observable_list;
-
-import 'dart:async';
-import 'dart:collection' show ListBase, UnmodifiableListView;
-
-import 'differs.dart';
-import 'records.dart';
-import 'observable.dart' show Observable;
-
-/// Represents an observable list of model values. If any items are added,
-/// removed, or replaced, then observers that are listening to [changes]
-/// will be notified.
-class ObservableList<E> extends ListBase<E> with Observable {
-  List<ListChangeRecord> _listRecords;
-
-  StreamController<List<ListChangeRecord>> _listChanges;
-
-  /// The inner [List<E>] with the actual storage.
-  final List<E> _list;
-
-  /// Creates an observable list of the given [length].
-  ///
-  /// If no [length] argument is supplied an extendable list of
-  /// length 0 is created.
-  ///
-  /// If a [length] argument is supplied, a fixed size list of that
-  /// length is created.
-  ObservableList([int length])
-      : _list = length != null ? new List<E>(length) : <E>[];
-
-  /// Creates an observable list of the given [length].
-  ///
-  /// This constructor exists to work around an issue in the VM whereby
-  /// classes that derive from [ObservableList] and mixin other classes
-  /// require a default generative constructor in the super class that
-  /// does not take optional arguments.
-  ObservableList.withLength(int length) : this(length);
-
-  /// Creates an observable list with the elements of [other]. The order in
-  /// the list will be the order provided by the iterator of [other].
-  factory ObservableList.from(Iterable<E> other) =>
-      new ObservableList<E>()..addAll(other);
-
-  /// The stream of summarized list changes, delivered asynchronously.
-  ///
-  /// Each list change record contains information about an individual mutation.
-  /// The records are projected so they can be applied sequentially. For
-  /// example, this set of mutations:
-  ///
-  ///     var model = new ObservableList.from(['a', 'b']);
-  ///     model.listChanges.listen((records) => records.forEach(print));
-  ///     model.removeAt(1);
-  ///     model.insertAll(0, ['c', 'd', 'e']);
-  ///     model.removeRange(1, 3);
-  ///     model.insert(1, 'f');
-  ///
-  /// The change records will be summarized so they can be "played back", using
-  /// the final list positions to figure out which item was added:
-  ///
-  ///     #<ListChangeRecord index: 0, removed: [], addedCount: 2>
-  ///     #<ListChangeRecord index: 3, removed: [b], addedCount: 0>
-  ///
-  /// [deliverChanges] can be called to force synchronous delivery.
-  Stream<List<ListChangeRecord>> get listChanges {
-    if (_listChanges == null) {
-      // TODO(jmesserly): split observed/unobserved notions?
-      _listChanges = new StreamController.broadcast(
-        sync: true,
-        onCancel: () {
-          _listChanges = null;
-        },
-      );
-    }
-    return _listChanges.stream;
-  }
-
-  bool get hasListObservers => _listChanges != null && _listChanges.hasListener;
-
-  @override
-  int get length => _list.length;
-
-  @override
-  set length(int value) {
-    int len = _list.length;
-    if (len == value) return;
-
-    // Produce notifications if needed
-    _notifyChangeLength(len, value);
-    if (hasListObservers) {
-      if (value < len) {
-        _notifyListChange(value, removed: _list.getRange(value, len).toList());
-      } else {
-        _notifyListChange(len, addedCount: value - len);
-      }
-    }
-
-    _list.length = value;
-  }
-
-  @override
-  E operator [](int index) => _list[index];
-
-  @override
-  void operator []=(int index, E value) {
-    E oldValue = _list[index];
-    if (hasListObservers && oldValue != value) {
-      _notifyListChange(index, addedCount: 1, removed: [oldValue]);
-    }
-    _list[index] = value;
-  }
-
-  // Forwarders so we can reflect on the properties.
-  @override
-  bool get isEmpty => super.isEmpty;
-
-  @override
-  bool get isNotEmpty => super.isNotEmpty;
-
-  // TODO(jmesserly): should we support first/last/single? They're kind of
-  // dangerous to use in a path because they throw exceptions. Also we'd need
-  // to produce property change notifications which seems to conflict with our
-  // existing list notifications.
-
-  // The following methods are here so that we can provide nice change events.
-  @override
-  void setAll(int index, Iterable<E> iterable) {
-    if (iterable is! List && iterable is! Set) {
-      iterable = iterable.toList();
-    }
-    int length = iterable.length;
-    if (hasListObservers && length > 0) {
-      _notifyListChange(index,
-          addedCount: length, removed: _list.sublist(index, length));
-    }
-    _list.setAll(index, iterable);
-  }
-
-  @override
-  void add(E value) {
-    int len = _list.length;
-    _notifyChangeLength(len, len + 1);
-    if (hasListObservers) {
-      _notifyListChange(len, addedCount: 1);
-    }
-
-    _list.add(value);
-  }
-
-  @override
-  void addAll(Iterable<E> iterable) {
-    int len = _list.length;
-    _list.addAll(iterable);
-
-    _notifyChangeLength(len, _list.length);
-
-    int added = _list.length - len;
-    if (hasListObservers && added > 0) {
-      _notifyListChange(len, addedCount: added);
-    }
-  }
-
-  @override
-  bool remove(Object element) {
-    for (int i = 0; i < this.length; i++) {
-      if (this[i] == element) {
-        removeRange(i, i + 1);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  void removeRange(int start, int end) {
-    _rangeCheck(start, end);
-    int rangeLength = end - start;
-    int len = _list.length;
-
-    _notifyChangeLength(len, len - rangeLength);
-    if (hasListObservers && rangeLength > 0) {
-      _notifyListChange(start, removed: _list.getRange(start, end).toList());
-    }
-
-    _list.removeRange(start, end);
-  }
-
-  @override
-  void insertAll(int index, Iterable<E> iterable) {
-    if (index < 0 || index > length) {
-      throw new RangeError.range(index, 0, length);
-    }
-    // TODO(floitsch): we can probably detect more cases.
-    if (iterable is! List && iterable is! Set) {
-      iterable = iterable.toList();
-    }
-    int insertionLength = iterable.length;
-    // There might be errors after the length change, in which case the list
-    // will end up being modified but the operation not complete. Unless we
-    // always go through a "toList" we can't really avoid that.
-    int len = _list.length;
-    _list.length += insertionLength;
-
-    _list.setRange(index + insertionLength, this.length, this, index);
-    _list.setAll(index, iterable);
-
-    _notifyChangeLength(len, _list.length);
-
-    if (hasListObservers && insertionLength > 0) {
-      _notifyListChange(index, addedCount: insertionLength);
-    }
-  }
-
-  @override
-  void insert(int index, E element) {
-    if (index < 0 || index > length) {
-      throw new RangeError.range(index, 0, length);
-    }
-    if (index == length) {
-      add(element);
-      return;
-    }
-    // We are modifying the length just below the is-check. Without the check
-    // Array.copy could throw an exception, leaving the list in a bad state
-    // (with a length that has been increased, but without a new element).
-    if (index is! int) throw new ArgumentError(index);
-    _list.length++;
-    _list.setRange(index + 1, length, this, index);
-
-    _notifyChangeLength(_list.length - 1, _list.length);
-    if (hasListObservers) {
-      _notifyListChange(index, addedCount: 1);
-    }
-    _list[index] = element;
-  }
-
-  @override
-  E removeAt(int index) {
-    E result = this[index];
-    removeRange(index, index + 1);
-    return result;
-  }
-
-  void _rangeCheck(int start, int end) {
-    if (start < 0 || start > this.length) {
-      throw new RangeError.range(start, 0, this.length);
-    }
-    if (end < start || end > this.length) {
-      throw new RangeError.range(end, start, this.length);
-    }
-  }
-
-  void _notifyListChange(
-    int index, {
-    List removed: const [],
-    int addedCount: 0,
-  }) {
-    if (!hasListObservers) return;
-    if (_listRecords == null) {
-      _listRecords = [];
-      scheduleMicrotask(deliverListChanges);
-    }
-    _listRecords.add(new ListChangeRecord(
-      this,
-      index,
-      removed: removed,
-      addedCount: addedCount,
-    ));
-  }
-
-  void _notifyChangeLength(int oldValue, int newValue) {
-    notifyPropertyChange(#length, oldValue, newValue);
-    notifyPropertyChange(#isEmpty, oldValue == 0, newValue == 0);
-    notifyPropertyChange(#isNotEmpty, oldValue != 0, newValue != 0);
-  }
-
-  void discardListChanges() {
-    // Leave _listRecords set so we don't schedule another delivery.
-    if (_listRecords != null) _listRecords = [];
-  }
-
-  bool deliverListChanges() {
-    if (_listRecords == null) return false;
-    List<ListChangeRecord> records =
-        projectListSplices/*<E>*/(this, _listRecords);
-    _listRecords = null;
-
-    if (hasListObservers && records.isNotEmpty) {
-      _listChanges.add(new UnmodifiableListView<ListChangeRecord>(records));
-      return true;
-    }
-    return false;
-  }
-
-  /// Calculates the changes to the list, if lacking individual splice mutation
-  /// information.
-  ///
-  /// This is not needed for change records produced by [ObservableList] itself,
-  /// but it can be used if the list instance was replaced by another list.
-  ///
-  /// The minimal set of splices can be synthesized given the previous state and
-  /// final state of a list. The basic approach is to calculate the edit
-  /// distance matrix and choose the shortest path through it.
-  ///
-  /// Complexity is `O(l * p)` where `l` is the length of the current list and
-  /// `p` is the length of the old list.
-  static List<ListChangeRecord/*<E>*/ > calculateChangeRecords/*<E>*/(
-    List/*<E>*/ oldValue,
-    List/*<E>*/ newValue,
-  ) {
-    return const ListDiffer/*<E>*/().diff(oldValue, newValue);
-  }
-
-  /// Updates the [previous] list using the [changeRecords]. For added items,
-  /// the [current] list is used to find the current value.
-  static void applyChangeRecords(List<Object> previous, List<Object> current,
-      List<ListChangeRecord> changeRecords) {
-    if (identical(previous, current)) {
-      throw new ArgumentError("can't use same list for previous and current");
-    }
-
-    for (ListChangeRecord change in changeRecords) {
-      int addEnd = change.index + change.addedCount;
-      int removeEnd = change.index + change.removed.length;
-
-      Iterable addedItems = current.getRange(change.index, addEnd);
-      previous.replaceRange(change.index, removeEnd, addedItems);
-    }
-  }
-}
diff --git a/lib/src/records/property_change_record.dart b/lib/src/records/property_change_record.dart
index 74566d5..a606649 100644
--- a/lib/src/records/property_change_record.dart
+++ b/lib/src/records/property_change_record.dart
@@ -26,6 +26,20 @@
   );
 
   @override
+  bool operator ==(Object o) {
+    if (o is PropertyChangeRecord<T>) {
+      return identical(object, o.object) &&
+          name == o.name &&
+          oldValue == o.oldValue &&
+          newValue == o.newValue;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode => hash4(object, name, oldValue, newValue);
+
+  @override
   String toString() => ''
       '#<$PropertyChangeRecord $name from $oldValue to: $newValue';
 }
diff --git a/lib/src/to_observable.dart b/lib/src/to_observable.dart
index 3bf24b6..d117c89 100644
--- a/lib/src/to_observable.dart
+++ b/lib/src/to_observable.dart
@@ -7,7 +7,7 @@
 import 'dart:collection';
 
 import 'observable.dart' show Observable;
-import 'observable_list.dart' show ObservableList;
+import 'collections.dart' show ObservableList;
 import 'observable_map.dart' show ObservableMap;
 
 /// Converts the [Iterable] or [Map] to an [ObservableList] or [ObservableMap],
diff --git a/pubspec.yaml b/pubspec.yaml
index f326c5d..57ce0ad 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: observable
-version: 0.17.0+1
+version: 0.18.0
 author: Dart Team <misc@dartlang.org>
 description: Support for marking objects as observable
 homepage: https://github.com/dart-lang/observable
diff --git a/test/collections/observable_list_test.dart b/test/collections/observable_list_test.dart
new file mode 100644
index 0000000..b8e50d0
--- /dev/null
+++ b/test/collections/observable_list_test.dart
@@ -0,0 +1,444 @@
+import 'dart:async';
+
+import 'package:observable/observable.dart';
+import 'package:test/test.dart';
+
+main() {
+  group('$ObservableList', () {
+    group('list api', _runListTests);
+    _runObservableListTests();
+    _runDeprecatedTests();
+  });
+}
+
+bool _hasListChanges(List<ChangeRecord> c) {
+  return c.any((r) => r is ListChangeRecord);
+}
+
+bool _hasPropChanges(List<ChangeRecord> c) {
+  return c.any((r) => r is PropertyChangeRecord);
+}
+
+bool _onlyListChanges(ChangeRecord c) => c is ListChangeRecord;
+
+bool _onlyPropRecords(ChangeRecord c) => c is PropertyChangeRecord;
+
+_runListTests() {
+  // TODO(matanl): Can we run the List-API tests from the SDK?
+  // Any methods actually implemented by ObservableList are below, otherwise I
+  // am relying on the test suite for DelegatingList.
+  test('index set operator', () {
+    final list = new ObservableList<String>(1)..[0] = 'value';
+    expect(list, ['value']);
+  });
+
+  test('add', () {
+    final list = new ObservableList<String>()..add('value');
+    expect(list, ['value']);
+  });
+
+  test('addAll', () {
+    final list = new ObservableList<String>()..addAll(['a', 'b', 'c']);
+    expect(list, ['a', 'b', 'c']);
+  });
+
+  test('clear', () {
+    final list = new ObservableList<String>.from(['a', 'b', 'c'])..clear();
+    expect(list, isEmpty);
+  });
+
+  test('fillRange', () {
+    final list = new ObservableList<String>(5)..fillRange(0, 5, 'a');
+    expect(list, ['a', 'a', 'a', 'a', 'a']);
+  });
+
+  test('insert', () {
+    final list = new ObservableList<String>.from(['a', 'c'])..insert(1, 'b');
+    expect(list, ['a', 'b', 'c']);
+  });
+
+  test('insertAll', () {
+    final list = new ObservableList<String>.from(['c']);
+    list.insertAll(0, ['a', 'b']);
+    expect(list, ['a', 'b', 'c']);
+  });
+
+  test('length', () {
+    final list = new ObservableList<String>()..length = 3;
+    expect(list, [null, null, null]);
+    list.length = 1;
+    expect(list, [null]);
+    list.length = 0;
+    expect(list, isEmpty);
+  });
+
+  test('remove', () {
+    final list = new ObservableList<String>.from(['a', 'b', 'c']);
+    expect(list.remove('b'), isTrue);
+    expect(list, ['a', 'c']);
+  });
+
+  test('removeAt', () {
+    final list = new ObservableList<String>.from(['a', 'b', 'c']);
+    expect(list.removeAt(1), 'b');
+    expect(list, ['a', 'c']);
+  });
+
+  test('removeLast', () {
+    final list = new ObservableList<String>.from(['a', 'b', 'c']);
+    expect(list.removeLast(), 'c');
+  });
+
+  test('removeRange', () {
+    final list = new ObservableList<String>.from(['a', 'b', 'c']);
+    list.removeRange(0, 2);
+    expect(list, ['c']);
+  });
+
+  test('removeWhere', () {
+    final list = new ObservableList<String>.from(['a', 'b', 'a', 'b']);
+    list.removeWhere((v) => v == 'a');
+    expect(list, ['b', 'b']);
+  });
+
+  test('retainWhere', () {
+    final list = new ObservableList<String>.from(['a', 'b', 'a', 'b']);
+    list.retainWhere((v) => v == 'a');
+    expect(list, ['a', 'a']);
+  });
+
+  test('setAll', () {
+    final list = new ObservableList<String>.from(['a', 'b', 'c']);
+    list.setAll(1, ['d', 'f']);
+    expect(list, ['a', 'd', 'f']);
+  });
+
+  test('setRange', () {
+    final list = new ObservableList<String>.from(['a', 'b', 'c']);
+    list.setRange(0, 2, ['d', 'e']);
+    expect(list, ['d', 'e', 'c']);
+    list.setRange(1, 3, ['f', 'g', 'h'], 1);
+    expect(list, ['d', 'g', 'h']);
+  });
+}
+
+// These are the tests we will keep after deprecations occur.
+_runObservableListTests() {
+  group('content changes', () {
+    Completer<List<ListChangeRecord>> completer;
+    List<String> previousState;
+
+    ObservableList<String> list;
+    Stream<List<ChangeRecord>> stream;
+    StreamSubscription sub;
+
+    Future next() {
+      completer = new Completer<List<ListChangeRecord>>.sync();
+      return completer.future;
+    }
+
+    Future<Null> expectChanges(List<ListChangeRecord> changes) {
+      // Applying these change records in order should make the new list.
+      for (final change in changes) {
+        change.apply(previousState);
+      }
+      expect(list, previousState);
+
+      // If these fail, it might be safe to update if optimized/changed.
+      return next().then((actualChanges) {
+        expect(actualChanges, changes);
+      });
+    }
+
+    setUp(() {
+      previousState = ['a', 'b', 'c'];
+      list = new ObservableList<String>.from(previousState);
+      stream = list.changes.where(_hasListChanges);
+      sub = stream.listen((c) {
+        if (completer?.isCompleted == false) {
+          completer.complete(c.where(_onlyListChanges).toList());
+        }
+        previousState = list.toList();
+      });
+    });
+
+    tearDown(() => sub.cancel());
+
+    ListChangeRecord _delta(
+      int index, {
+      List removed: const [],
+      int addedCount: 0,
+    }) {
+      return new ListChangeRecord(
+        list,
+        index,
+        removed: removed,
+        addedCount: addedCount,
+      );
+    }
+
+    test('operator[]=', () async {
+      list[0] = 'd';
+      await expectChanges([
+        _delta(0, removed: ['a'], addedCount: 1),
+      ]);
+    });
+
+    test('add', () async {
+      list.add('d');
+      await expectChanges([
+        _delta(3, addedCount: 1),
+      ]);
+    });
+
+    test('addAll', () async {
+      list.addAll(['d', 'e']);
+      await expectChanges([
+        _delta(3, addedCount: 2),
+      ]);
+    });
+
+    test('clear', () async {
+      list.clear();
+      await expectChanges([
+        _delta(0, removed: ['a', 'b', 'c']),
+      ]);
+    });
+
+    test('fillRange', () async {
+      list.fillRange(1, 3, 'd');
+      await expectChanges([
+        _delta(1, removed: ['b', 'c'], addedCount: 2),
+      ]);
+    });
+
+    test('insert', () async {
+      list.insert(1, 'd');
+      await expectChanges([
+        _delta(1, addedCount: 1),
+      ]);
+    });
+
+    test('insertAll', () async {
+      list.insertAll(1, ['d', 'e']);
+      await expectChanges([
+        _delta(1, addedCount: 2),
+      ]);
+    });
+
+    test('length', () async {
+      list.length = 5;
+      await expectChanges([
+        _delta(3, addedCount: 2),
+      ]);
+      list.length = 1;
+      await expectChanges([
+        _delta(1, removed: ['b', 'c', null, null])
+      ]);
+    });
+
+    test('remove', () async {
+      list.remove('b');
+      await expectChanges([
+        _delta(1, removed: ['b'])
+      ]);
+    });
+
+    test('removeAt', () async {
+      list.removeAt(1);
+      await expectChanges([
+        _delta(1, removed: ['b'])
+      ]);
+    });
+
+    test('removeRange', () async {
+      list.removeRange(0, 2);
+      await expectChanges([
+        _delta(0, removed: ['a', 'b'])
+      ]);
+    });
+
+    test('removeWhere', () async {
+      list.removeWhere((s) => s == 'b');
+      await expectChanges([
+        _delta(1, removed: ['b'])
+      ]);
+    });
+
+    test('replaceRange', () async {
+      list.replaceRange(0, 2, ['d', 'e']);
+      await expectChanges([
+        // Normally would be
+        //   _delta(0, removed: ['a', 'b']),
+        //   _delta(0, addedCount: 2),
+        // But projectListSplices(...) optimizes to single record
+        _delta(0, removed: ['a', 'b'], addedCount: 2),
+      ]);
+    });
+
+    test('retainWhere', () async {
+      list.retainWhere((s) => s == 'b');
+      await expectChanges([
+        _delta(0, removed: ['a']),
+        _delta(1, removed: ['c']),
+      ]);
+    });
+
+    test('setAll', () async {
+      list.setAll(1, ['d', 'e']);
+      await expectChanges([
+        _delta(1, removed: ['b', 'c'], addedCount: 2),
+      ]);
+    });
+
+    test('setRange', () async {
+      list.setRange(0, 2, ['d', 'e']);
+      await expectChanges([
+        _delta(0, removed: ['a', 'b'], addedCount: 2),
+      ]);
+      list.setRange(1, 3, ['f', 'g', 'h'], 1);
+      await expectChanges([
+        _delta(1, removed: ['e', 'c'], addedCount: 2),
+      ]);
+    });
+  });
+}
+
+// These are tests we will remove after deprecations occur.
+_runDeprecatedTests() {
+  group('length changes', () {
+    Completer<List<ListChangeRecord>> completer;
+    ObservableList<String> list;
+    Stream<List<ChangeRecord>> stream;
+    StreamSubscription sub;
+
+    Future next() {
+      completer = new Completer<List<ListChangeRecord>>.sync();
+      return completer.future;
+    }
+
+    setUp(() {
+      list = new ObservableList<String>.from(['a', 'b', 'c']);
+      stream = list.changes.where(_hasPropChanges);
+      sub = stream.listen((c) {
+        if (completer?.isCompleted == false) {
+          completer.complete(c.where(_onlyPropRecords).toList());
+        }
+      });
+    });
+
+    tearDown(() => sub.cancel());
+
+    PropertyChangeRecord _length(int oldLength, int newLength) {
+      return new PropertyChangeRecord(list, #length, oldLength, newLength);
+    }
+
+    PropertyChangeRecord _isEmpty(bool oldValue, bool newValue) {
+      return new PropertyChangeRecord(list, #isEmpty, oldValue, newValue);
+    }
+
+    PropertyChangeRecord _isNotEmpty(bool oldValue, bool newValue) {
+      return new PropertyChangeRecord(list, #isNotEmpty, oldValue, newValue);
+    }
+
+    test('add', () async {
+      list.add('d');
+      expect(await next(), [
+        _length(3, 4),
+      ]);
+    });
+
+    test('addAll', () async {
+      list.addAll(['d', 'e']);
+      expect(await next(), [
+        _length(3, 5),
+      ]);
+    });
+
+    test('clear', () async {
+      list.clear();
+      expect(await next(), [
+        _length(3, 0),
+        _isEmpty(false, true),
+        _isNotEmpty(true, false),
+      ]);
+    });
+
+    test('insert', () async {
+      list.insert(0, 'd');
+      expect(await next(), [
+        _length(3, 4),
+      ]);
+    });
+
+    test('insertAll', () async {
+      list.insertAll(0, ['d', 'e']);
+      expect(await next(), [
+        _length(3, 5),
+      ]);
+    });
+
+    test('length', () async {
+      list.length = 5;
+      expect(await next(), [
+        _length(3, 5),
+      ]);
+
+      list.length = 0;
+      expect(await next(), [
+        _length(5, 0),
+        _isEmpty(false, true),
+        _isNotEmpty(true, false),
+      ]);
+
+      list.length = 1;
+      expect(await next(), [
+        _length(0, 1),
+        _isEmpty(true, false),
+        _isNotEmpty(false, true),
+      ]);
+    });
+
+    test('remove', () async {
+      list.remove('a');
+      expect(await next(), [
+        _length(3, 2),
+      ]);
+    });
+
+    test('removeAt', () async {
+      list.removeAt(0);
+      expect(await next(), [
+        _length(3, 2),
+      ]);
+    });
+
+    test('removeLast', () async {
+      list.removeLast();
+      expect(await next(), [
+        _length(3, 2),
+      ]);
+    });
+
+    test('removeRange', () async {
+      list.removeRange(0, 2);
+      expect(await next(), [
+        _length(3, 1),
+      ]);
+    });
+
+    test('removeWhere', () async {
+      list.removeWhere((s) => s == 'a');
+      expect(await next(), [
+        _length(3, 2),
+      ]);
+    });
+
+    test('retainWhere', () async {
+      list.retainWhere((s) => s == 'a');
+      expect(await next(), [
+        _length(3, 1),
+      ]);
+    });
+  });
+}
diff --git a/test/observable_list_test.dart b/test/observable_list_test.dart
deleted file mode 100644
index ed87d04..0000000
--- a/test/observable_list_test.dart
+++ /dev/null
@@ -1,342 +0,0 @@
-// Copyright (c) 2016, 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.
-
-import 'dart:async';
-
-import 'package:observable/observable.dart';
-import 'package:test/test.dart';
-
-import 'observable_test_utils.dart';
-
-main() => _runTests();
-
-_runTests() {
-  // TODO(jmesserly): need all standard List API tests.
-
-  StreamSubscription sub, sub2;
-
-  sharedTearDown() {
-    list = null;
-    sub.cancel();
-    if (sub2 != null) {
-      sub2.cancel();
-      sub2 = null;
-    }
-  }
-
-  group('observe length', () {
-    ObservableList list;
-    List<ChangeRecord> changes;
-
-    setUp(() {
-      list = toObservable([1, 2, 3]) as ObservableList;
-      changes = null;
-      sub = list.changes.listen((records) {
-        changes = getPropertyChangeRecords(records, #length);
-      });
-    });
-
-    tearDown(sharedTearDown);
-
-    test('add changes length', () {
-      list.add(4);
-      expect(list, [1, 2, 3, 4]);
-      return new Future(() {
-        expectChanges(changes, [_lengthChange(3, 4)]);
-      });
-    });
-
-    test('removeObject changes length', () {
-      list.remove(2);
-      expect(list, orderedEquals([1, 3]));
-
-      return new Future(() {
-        expectChanges(changes, [_lengthChange(3, 2)]);
-      });
-    });
-
-    test('removeRange changes length', () {
-      list.add(4);
-      list.removeRange(1, 3);
-      expect(list, [1, 4]);
-      return new Future(() {
-        expectChanges(changes, [_lengthChange(3, 4), _lengthChange(4, 2)]);
-      });
-    });
-
-    test('removeWhere changes length', () {
-      list.add(2);
-      list.removeWhere((e) => e == 2);
-      expect(list, [1, 3]);
-      return new Future(() {
-        expectChanges(changes, [_lengthChange(3, 4), _lengthChange(4, 2)]);
-      });
-    });
-
-    test('length= changes length', () {
-      list.length = 5;
-      expect(list, [1, 2, 3, null, null]);
-      return new Future(() {
-        expectChanges(changes, [_lengthChange(3, 5)]);
-      });
-    });
-
-    test('[]= does not change length', () {
-      list[2] = 9000;
-      expect(list, [1, 2, 9000]);
-      return new Future(() {
-        expectChanges(changes, null);
-      });
-    });
-
-    test('clear changes length', () {
-      list.clear();
-      expect(list, []);
-      return new Future(() {
-        expectChanges(changes, [_lengthChange(3, 0)]);
-      });
-    });
-  });
-
-  group('observe index', () {
-    List<ListChangeRecord> changes;
-
-    setUp(() {
-      list = toObservable([1, 2, 3]) as ObservableList;
-      changes = null;
-      sub = list.listChanges.listen((List<ListChangeRecord> records) {
-        changes = getListChangeRecords(records, 1);
-      });
-    });
-
-    tearDown(sharedTearDown);
-
-    test('add does not change existing items', () {
-      list.add(4);
-      expect(list, [1, 2, 3, 4]);
-      return new Future(() {
-        expectChanges(changes, []);
-      });
-    });
-
-    test('[]= changes item', () {
-      list[1] = 777;
-      expect(list, [1, 777, 3]);
-      return new Future(() {
-        expectChanges(changes, [
-          _change(1, addedCount: 1, removed: [2])
-        ]);
-      });
-    });
-
-    test('[]= on a different item does not fire change', () {
-      list[2] = 9000;
-      expect(list, [1, 2, 9000]);
-      return new Future(() {
-        expectChanges(changes, []);
-      });
-    });
-
-    test('set multiple times results in one change', () {
-      list[1] = 777;
-      list[1] = 42;
-      expect(list, [1, 42, 3]);
-      return new Future(() {
-        expectChanges(changes, [
-          _change(1, addedCount: 1, removed: [2]),
-        ]);
-      });
-    });
-
-    test('set length without truncating item means no change', () {
-      list.length = 2;
-      expect(list, [1, 2]);
-      return new Future(() {
-        expectChanges(changes, []);
-      });
-    });
-
-    test('truncate removes item', () {
-      list.length = 1;
-      expect(list, [1]);
-      return new Future(() {
-        expectChanges(changes, [
-          _change(1, removed: [2, 3])
-        ]);
-      });
-    });
-
-    test('truncate and add new item', () {
-      list.length = 1;
-      list.add(42);
-      expect(list, [1, 42]);
-      return new Future(() {
-        expectChanges(changes, [
-          _change(1, removed: [2, 3], addedCount: 1)
-        ]);
-      });
-    });
-
-    test('truncate and add same item', () {
-      list.length = 1;
-      list.add(2);
-      expect(list, [1, 2]);
-      return new Future(() {
-        expectChanges(changes, []);
-      });
-    });
-  });
-
-  test('toString', () {
-    var list = toObservable([1, 2, 3]);
-    expect(list.toString(), '[1, 2, 3]');
-  });
-
-  group('change records', () {
-    List<ChangeRecord> propRecords;
-    List<ListChangeRecord> listRecords;
-
-    setUp(() {
-      list = toObservable([1, 2, 3, 1, 3, 4]) as ObservableList;
-      propRecords = null;
-      listRecords = null;
-      sub = list.changes.listen((r) => propRecords = r);
-      sub2 = list.listChanges.listen((r) => listRecords = r);
-    });
-
-    tearDown(sharedTearDown);
-
-    test('read operations', () {
-      expect(list.length, 6);
-      expect(list[0], 1);
-      expect(list.indexOf(4), 5);
-      expect(list.indexOf(1), 0);
-      expect(list.indexOf(1, 1), 3);
-      expect(list.lastIndexOf(1), 3);
-      expect(list.last, 4);
-      var copy = new List<int>();
-      list.forEach((int i) => copy.add(i));
-      expect(copy, orderedEquals([1, 2, 3, 1, 3, 4]));
-      return new Future(() {
-        // no change from read-only operators
-        expectChanges(propRecords, null);
-        expectChanges(listRecords, null);
-      });
-    });
-
-    test('add', () {
-      list.add(5);
-      list.add(6);
-      expect(list, orderedEquals([1, 2, 3, 1, 3, 4, 5, 6]));
-
-      return new Future(() {
-        expectChanges(propRecords, [
-          _lengthChange(6, 7),
-          _lengthChange(7, 8),
-        ]);
-        expectChanges(listRecords, [_change(6, addedCount: 2)]);
-      });
-    });
-
-    test('[]=', () {
-      list[1] = list.last;
-      expect(list, orderedEquals([1, 4, 3, 1, 3, 4]));
-
-      return new Future(() {
-        expectChanges(propRecords, null);
-        expectChanges(listRecords, [
-          _change(1, addedCount: 1, removed: [2])
-        ]);
-      });
-    });
-
-    test('removeLast', () {
-      expect(list.removeLast(), 4);
-      expect(list, orderedEquals([1, 2, 3, 1, 3]));
-
-      return new Future(() {
-        expectChanges(propRecords, [_lengthChange(6, 5)]);
-        expectChanges(listRecords, [
-          _change(5, removed: [4])
-        ]);
-      });
-    });
-
-    test('removeRange', () {
-      list.removeRange(1, 4);
-      expect(list, orderedEquals([1, 3, 4]));
-
-      return new Future(() {
-        expectChanges(propRecords, [_lengthChange(6, 3)]);
-        expectChanges(listRecords, [
-          _change(1, removed: [2, 3, 1])
-        ]);
-      });
-    });
-
-    test('removeWhere', () {
-      list.removeWhere((e) => e == 3);
-      expect(list, orderedEquals([1, 2, 1, 4]));
-
-      return new Future(() {
-        expectChanges(propRecords, [_lengthChange(6, 4)]);
-        expectChanges(listRecords, [
-          _change(2, removed: [3]),
-          _change(3, removed: [3])
-        ]);
-      });
-    });
-
-    test('sort', () {
-      list.sort((x, y) => x - y);
-      expect(list, orderedEquals([1, 1, 2, 3, 3, 4]));
-
-      return new Future(() {
-        expectChanges(propRecords, null);
-        expectChanges(listRecords, [
-          _change(1, addedCount: 1),
-          _change(4, removed: [1])
-        ]);
-      });
-    });
-
-    test('sort of 2 elements', () {
-      var list = toObservable([3, 1]);
-      // Dummy listener to record changes.
-      // TODO(jmesserly): should we just record changes always, to support the sync api?
-      sub = list.listChanges.listen((List<ListChangeRecord> records) => null)
-          as StreamSubscription;
-      list.sort();
-      expect(list.deliverListChanges(), true);
-      list.sort();
-      expect(list.deliverListChanges(), false);
-      list.sort();
-      expect(list.deliverListChanges(), false);
-    });
-
-    test('clear', () {
-      list.clear();
-      expect(list, []);
-
-      return new Future(() {
-        expectChanges(propRecords, [
-          _lengthChange(6, 0),
-          new PropertyChangeRecord(list, #isEmpty, false, true),
-          new PropertyChangeRecord(list, #isNotEmpty, true, false),
-        ]);
-        expectChanges(listRecords, [
-          _change(0, removed: [1, 2, 3, 1, 3, 4])
-        ]);
-      });
-    });
-  });
-}
-
-ObservableList list;
-
-PropertyChangeRecord _lengthChange(int oldValue, int newValue) =>
-    new PropertyChangeRecord(list, #length, oldValue, newValue);
-
-_change(int index, {List removed: const [], int addedCount: 0}) =>
-    new ListChangeRecord(list, index, removed: removed, addedCount: addedCount);
diff --git a/test/observable_test_utils.dart b/test/observable_test_utils.dart
index 990cc86..9ce9161 100644
--- a/test/observable_test_utils.dart
+++ b/test/observable_test_utils.dart
@@ -17,8 +17,9 @@
 
 // TODO(jmesserly): use matchers when we have a way to compare ChangeRecords.
 // For now just use the toString.
-void expectChanges(actual, expected, {String reason}) =>
-    expect('$actual', '$expected', reason: reason);
+void expectChanges(actual, expected, {String reason}) {
+  expect('$actual', '$expected', reason: reason);
+}
 
 List<ListChangeRecord> getListChangeRecords(
         List<ListChangeRecord> changes, int index) =>
