diff --git a/.travis.yml b/.travis.yml
index b70d6ec..029d2e2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,28 +3,20 @@
 dart:
   - stable
   - dev
-  - 1.22.1
 addons:
   # otherwise a number of tests in test/security/html_sanitizer_test.dart fail
   firefox: "latest"
 dart_task:
+  - dartanalyzer: --fatal-warnings .
   - test: --platform vm
   # Disable parallelism on Firefox (-j 1)
   # Causes flakiness – need to investigate
   - test: --platform firefox -j 1
 matrix:
-  include:
-    # Only validate formatting using the dev release
-    # Formatted with 1.23.0-dev.10.0 which has (good) changes since 1.22.1
-    - dart: dev
-      dart_task: dartfmt
-    # Only care about being analyzer clean for dev and stable
-    - dart: dev
-      dart_task:
-        dartanalyzer: --fatal-warnings lib
-    - dart: stable
-      dart_task:
-        dartanalyzer: --fatal-warnings lib
+  allow_failures:
+  # Until Dart 2 becomes stable
+  - dart: stable
+
 cache:
   directories:
     - $HOME/.pub-cache
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2fc0934..9abaede 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+## 0.21.0
+
+### Breaking Changes
+
+Version 0.21.0 reverts to version 0.17.0+1 with fixes to support Dart 2.
+Versions 0.18, 0.19, and 0.20 were effectively unsupported. This resolves the
+fork that happened at version 0.18 and development can now be supported by the
+authors.
+
 ## 0.20.4+3
 
 * Support the latest release of `pkg/quiver` (0.27).
diff --git a/README.md b/README.md
index 639e746..bd82499 100644
--- a/README.md
+++ b/README.md
@@ -18,67 +18,3 @@
 
 * Listen to `Observable.changes` and be notified when an object changes
 * Use `Differ.diff` to determine changes between two objects
-
-### Examples
-
-Operations on Lists:
-
-```dart
-import 'package:observable/observable.dart';
-
-void main() {
-  var changes;
-
-  ObservableList<String> list = new ObservableList<String>.from(['a', 'b', 'c']);
-  StreamSubscription sub = list.listChanges.listen((c) => changes = c);
-
-  ListChangeRecord _delta(
-    int index, {
-    List removed: const [],
-    int addedCount: 0,
-  }) {
-    return new ListChangeRecord(
-      list,
-      index,
-      removed: removed,
-      addedCount: addedCount,
-    );
-  }
-
-  list.insertAll(1, ['y', 'z']); // changes == [_delta(1, addedCount: 2)]
-}
-```
-
-Diffing two maps:
-
-```dart
-import 'package:observable/observable.dart';
-
-void main() {
-  final map1 = {
-    'key-a': 'value-a',
-    'key-b': 'value-b-old',
-  };
-
-  final map2 = {
-    'key-a': 'value-a',
-    'key-b': 'value-b-new',
-  };
-
-  var diffResult = diff(map1,
-      map2); // [ new MapChangeRecord('key-b', 'value-b-old', 'value-b-new')]
-}
-```
-
-Diffing two sets:
-
-```dart
-import 'package:observable/observable.dart';
-
-void main() {
-  diff(
-    new Set<String>.from(['a', 'b']),
-    new Set<String>.from(['a']),
-  ); // [ new SetChangeRecord.remove('b') ]
-}
-```
diff --git a/.analysis_options b/analysis_options.yaml
similarity index 100%
rename from .analysis_options
rename to analysis_options.yaml
diff --git a/lib/observable.dart b/lib/observable.dart
index be4fe34..516ff70 100644
--- a/lib/observable.dart
+++ b/lib/observable.dart
@@ -5,15 +5,10 @@
 library observable;
 
 export 'src/change_notifier.dart' show ChangeNotifier, PropertyChangeNotifier;
-export 'src/collections.dart' show ObservableList, ObservableMap, ObservableSet;
-export 'src/differs.dart'
-    show Differ, EqualityDiffer, ListDiffer, MapDiffer, SetDiffer;
+export 'src/differs.dart' show Differ, EqualityDiffer, ListDiffer, MapDiffer;
 export 'src/records.dart'
-    show
-        ChangeRecord,
-        ListChangeRecord,
-        MapChangeRecord,
-        PropertyChangeRecord,
-        SetChangeRecord;
+    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 6ba9c9b..82d4e51 100644
--- a/lib/src/change_notifier.dart
+++ b/lib/src/change_notifier.dart
@@ -1,7 +1,3 @@
-// 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:meta/meta.dart';
@@ -10,11 +6,6 @@
 import 'observable.dart';
 import 'records.dart';
 
-// Temporarily exists to keep 'discard changes' API working for now.
-void internalDiscardChanges(ChangeNotifier changeNotifier) {
-  changeNotifier._queue = null;
-}
-
 /// Supplies [changes] and various hooks to implement [Observable].
 ///
 /// May use [notifyChange] to queue a change record; they are asynchronously
@@ -58,6 +49,7 @@
   ///
   /// Returns `true` if changes were emitted.
   @override
+  @visibleForTesting
   @mustCallSuper
   bool deliverChanges() {
     List<ChangeRecord> changes;
diff --git a/lib/src/collections.dart b/lib/src/collections.dart
deleted file mode 100644
index 7441831..0000000
--- a/lib/src/collections.dart
+++ /dev/null
@@ -1,7 +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.
-
-export 'collections/observable_list.dart';
-export 'collections/observable_map.dart';
-export 'collections/observable_set.dart';
diff --git a/lib/src/collections/observable_list.dart b/lib/src/collections/observable_list.dart
deleted file mode 100644
index 6e48e86..0000000
--- a/lib/src/collections/observable_list.dart
+++ /dev/null
@@ -1,519 +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:collection/collection.dart';
-import 'package:observable/observable.dart';
-import 'package:observable/src/change_notifier.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 {
-  /// An empty observable list that never has changes.
-  static const ObservableList EMPTY = const _ObservableUnmodifiableList(
-    const [],
-  );
-
-  /// 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);
-  }
-
-  /// Create new unmodifiable list from [list].
-  ///
-  /// [ObservableList.changes] and [ObservableList.listChanges] both always
-  /// return an empty stream, and mutating or adding change records throws an
-  /// [UnsupportedError].
-  factory ObservableList.unmodifiable(
-    List<E> list,
-  ) {
-    if (list is! UnmodifiableListView<E>) {
-      list = new List<E>.unmodifiable(list);
-    }
-    return new _ObservableUnmodifiableList<E>(list);
-  }
-
-  @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() {
-    internalDiscardChanges(_listChanges);
-  }
-
-  @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))
-        .where((r) => r.isNotEmpty && r != ChangeRecord.ANY);
-  }
-
-  @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);
-    }
-  }
-}
-
-class _ObservableUnmodifiableList<E> extends DelegatingList<E>
-    implements ObservableList<E> {
-  const _ObservableUnmodifiableList(List<E> list) : super(list);
-
-  @override
-  Stream<List<ChangeRecord>> get changes => const Stream.empty();
-
-  @override
-  bool deliverChanges() => false;
-
-  @override
-  bool deliverListChanges() => false;
-
-  @override
-  void discardListChanges() {}
-
-  @override
-  final bool hasListObservers = false;
-
-  @override
-  final bool hasObservers = false;
-
-  @override
-  Stream<List<ListChangeRecord<E>>> get listChanges => const Stream.empty();
-
-  @override
-  void notifyChange([ChangeRecord change]) {
-    throw new UnsupportedError('Not modifiable');
-  }
-
-  @override
-  void notifyListChange(
-    int index, {
-    List<E> removed: const [],
-    int addedCount: 0,
-  }) {
-    throw new UnsupportedError('Not modifiable');
-  }
-
-  @override
-  T notifyPropertyChange<T>(
-    Symbol field,
-    T oldValue,
-    T newValue,
-  ) {
-    throw new UnsupportedError('Not modifiable');
-  }
-
-  @override
-  void observed() {}
-
-  @override
-  void unobserved() {}
-}
diff --git a/lib/src/collections/observable_map.dart b/lib/src/collections/observable_map.dart
deleted file mode 100644
index 3b9cc09..0000000
--- a/lib/src/collections/observable_map.dart
+++ /dev/null
@@ -1,235 +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 'dart:collection';
-
-import 'package:collection/collection.dart';
-import 'package:observable/observable.dart';
-
-/// A [Map] 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 updated key-value). You may
-/// accept an observable map to be notified of mutations:
-///     ```
-///     set grades(Map<String, int> grades) {
-///       buildBook(grades);
-///       if (names is ObservableMap<String, int>) {
-///         grades.changes.listen(updateBook);
-///       }
-///     }
-///     ```
-///
-/// *See [MapDiffer] to manually diff two lists instead*
-abstract class ObservableMap<K, V> implements Map<K, V>, Observable {
-  /// An empty observable map that never has changes.
-  static const ObservableMap EMPTY = const _ObservableUnmodifiableMap(const {});
-
-  /// Creates a new observable map.
-  factory ObservableMap() {
-    return new _ObservableDelegatingMap(new HashMap<K, V>());
-  }
-
-  /// Like [ObservableMap.from], but creates an empty type.
-  factory ObservableMap.createFromType(Map<K, V> other) {
-    ObservableMap<K, V> result;
-    if (other is LinkedHashMap) {
-      result = new ObservableMap<K, V>.linked();
-    } else if (other is SplayTreeMap) {
-      result = new ObservableMap<K, V>.sorted();
-    } else {
-      result = new ObservableMap<K, V>();
-    }
-    return result;
-  }
-
-  /// Create a new observable map using [map] as a backing store.
-  factory ObservableMap.delegate(Map<K, V> map) {
-    return new _ObservableDelegatingMap<K, V>(map);
-  }
-
-  /// Creates a new observable map that contains all entries in [other].
-  ///
-  /// It will attempt to use the same backing map type if the other map is
-  /// either a [LinkedHashMap], [SplayTreeMap], or [HashMap]. Otherwise it will
-  /// fall back to using a [HashMap].
-  factory ObservableMap.from(Map<K, V> other) {
-    return new ObservableMap<K, V>.createFromType(other)..addAll(other);
-  }
-
-  /// Creates a new observable map using a [LinkedHashMap].
-  factory ObservableMap.linked() {
-    return new _ObservableDelegatingMap<K, V>(new LinkedHashMap<K, V>());
-  }
-
-  /// Creates a new observable map using a [SplayTreeMap].
-  factory ObservableMap.sorted() {
-    return new _ObservableDelegatingMap<K, V>(new SplayTreeMap<K, V>());
-  }
-
-  /// Creates a new observable map wrapping [other].
-  @Deprecated('Use ObservableMap.delegate for API consistency')
-  factory ObservableMap.spy(Map<K, V> other) = ObservableMap<K, V>.delegate;
-
-  /// Create a new unmodifiable map from [map].
-  ///
-  /// [ObservableMap.changes] always returns an empty stream, and mutating or
-  /// adding change records throws an [UnsupportedError].
-  factory ObservableMap.unmodifiable(Map<K, V> map) {
-    if (map is! UnmodifiableMapView<K, V>) {
-      map = new Map<K, V>.unmodifiable(map);
-    }
-    return new _ObservableUnmodifiableMap(map);
-  }
-}
-
-class _ObservableDelegatingMap<K, V> extends DelegatingMap<K, V>
-    implements ObservableMap<K, V> {
-  final _allChanges = new ChangeNotifier();
-
-  _ObservableDelegatingMap(Map<K, V> map) : super(map);
-
-  // Observable
-
-  @override
-  Stream<List<ChangeRecord>> get changes => _allChanges.changes;
-
-  // ChangeNotifier (deprecated for ObservableMap)
-
-  @override
-  bool deliverChanges() => _allChanges.deliverChanges();
-
-  @override
-  bool get hasObservers => _allChanges.hasObservers;
-
-  @override
-  void notifyChange([ChangeRecord change]) {
-    if (change is MapChangeRecord && change.oldValue == change.newValue) {
-      return;
-    }
-    _allChanges.notifyChange(change);
-  }
-
-  @override
-  T notifyPropertyChange<T>(
-    Symbol field,
-    T oldValue,
-    T newValue,
-  ) {
-    if (oldValue != newValue) {
-      _allChanges.notifyChange(
-        new PropertyChangeRecord<T>(this, field, oldValue, newValue),
-      );
-    }
-    return newValue;
-  }
-
-  @override
-  void observed() {}
-
-  @override
-  void unobserved() {}
-
-  @override
-  operator []=(K key, V newValue) {
-    if (!hasObservers) {
-      super[key] = newValue;
-      return;
-    }
-
-    final oldLength = super.length;
-    V oldValue = super[key];
-    super[key] = newValue;
-
-    if (oldLength != length) {
-      notifyPropertyChange(#length, oldLength, length);
-      notifyChange(new MapChangeRecord<K, V>.insert(key, newValue));
-    } else {
-      notifyChange(new MapChangeRecord<K, V>(key, oldValue, newValue));
-    }
-  }
-
-  @override
-  void addAll(Map<K, V> other) {
-    if (!hasObservers) {
-      super.addAll(other);
-      return;
-    }
-
-    other.forEach((k, v) => this[k] = v);
-  }
-
-  @override
-  V putIfAbsent(K key, V ifAbsent()) {
-    final oldLength = length;
-    final result = super.putIfAbsent(key, ifAbsent);
-    if (hasObservers && oldLength != length) {
-      notifyPropertyChange(#length, oldLength, length);
-      notifyChange(new MapChangeRecord<K, V>.insert(key, result));
-    }
-    return result;
-  }
-
-  @override
-  V remove(Object key) {
-    final oldLength = length;
-    final result = super.remove(key);
-    if (hasObservers && oldLength != length) {
-      notifyChange(new MapChangeRecord<K, V>.remove(key as K, result));
-      notifyPropertyChange(#length, oldLength, length);
-    }
-    return result;
-  }
-
-  @override
-  void clear() {
-    if (!hasObservers || isEmpty) {
-      super.clear();
-      return;
-    }
-    final oldLength = length;
-    forEach((k, v) {
-      notifyChange(new MapChangeRecord<K, V>.remove(k, v));
-    });
-    notifyPropertyChange(#length, oldLength, 0);
-    super.clear();
-  }
-}
-
-class _ObservableUnmodifiableMap<K, V> extends DelegatingMap<K, V>
-    implements ObservableMap<K, V> {
-  const _ObservableUnmodifiableMap(Map<K, V> map) : super(map);
-
-  @override
-  Stream<List<ChangeRecord>> get changes => const Stream.empty();
-
-  @override
-  bool deliverChanges() => false;
-
-  // TODO: implement hasObservers
-  @override
-  final bool hasObservers = false;
-
-  @override
-  void notifyChange([ChangeRecord change]) {
-    throw new UnsupportedError('Not modifiable');
-  }
-
-  @override
-  T notifyPropertyChange<T>(
-    Symbol field,
-    T oldValue,
-    T newValue,
-  ) {
-    throw new UnsupportedError('Not modifiable');
-  }
-
-  @override
-  void observed() {}
-
-  @override
-  void unobserved() {}
-}
diff --git a/lib/src/collections/observable_set.dart b/lib/src/collections/observable_set.dart
deleted file mode 100644
index 1117a29..0000000
--- a/lib/src/collections/observable_set.dart
+++ /dev/null
@@ -1,216 +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 'dart:collection';
-
-import 'package:collection/collection.dart';
-import 'package:observable/observable.dart';
-
-/// A [Set] 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 element). You may
-/// accept an observable set to be notified of mutations:
-/// ```
-/// set emails(Set<String> emails) {
-///   emailUsers(emails);
-///   if (names is ObservableSet<String>) {
-///     emails.changes.listen(updateEmailList);
-///   }
-/// }
-/// ```
-///
-/// *See [SetDiffer] to manually diff two lists instead*
-abstract class ObservableSet<E>
-    implements Observable<SetChangeRecord<E>>, Set<E> {
-  /// An empty observable set that never has changes.
-  static const ObservableSet EMPTY = const _UnmodifiableObservableSet(
-    const _UnmodifiableEmptySet(),
-  );
-
-  /// Create a new empty observable set.
-  factory ObservableSet() => new _DelegatingObservableSet<E>(new HashSet<E>());
-
-  /// Like [ObservableSet.from], but creates a new empty set.
-  factory ObservableSet.createFromType(Iterable<E> other) {
-    ObservableSet<E> result;
-    if (other is LinkedHashSet) {
-      result = new _DelegatingObservableSet<E>(new LinkedHashSet<E>());
-    } else if (result is SplayTreeSet) {
-      result = new _DelegatingObservableSet<E>(new SplayTreeSet<E>());
-    } else {
-      result = new _DelegatingObservableSet<E>(new HashSet<E>());
-    }
-    return result;
-  }
-
-  /// Create a new observable set using [set] as a backing store.
-  factory ObservableSet.delegate(Set<E> set) = _DelegatingObservableSet<E>;
-
-  /// Creates a new observable set that contains all elements in [other].
-  ///
-  /// It will attempt to use the same backing set type if the other set is
-  /// either a [LinkedHashSet], [SplayTreeSet], or [HashSet]. Otherwise it will
-  /// fall back to using a [HashSet].
-  factory ObservableSet.from(Iterable<E> other) {
-    return new ObservableSet<E>.createFromType(other)..addAll(other);
-  }
-
-  /// Creates a new observable map using a [LinkedHashSet].
-  factory ObservableSet.linked() {
-    return new _DelegatingObservableSet<E>(new LinkedHashSet<E>());
-  }
-
-  /// Creates a new observable map using a [SplayTreeSet].
-  factory ObservableSet.sorted() {
-    return new _DelegatingObservableSet<E>(new SplayTreeSet<E>());
-  }
-
-  /// Create a new unmodifiable set from [set].
-  ///
-  /// [ObservableSet.changes] always returns an empty stream, and mutating or
-  /// adding change records throws an [UnsupportedError].
-  factory ObservableSet.unmodifiable(Set<E> set) {
-    if (set is! UnmodifiableSetView<E>) {
-      set = new UnmodifiableSetView<E>(set);
-    }
-    return new _UnmodifiableObservableSet(set);
-  }
-}
-
-class _DelegatingObservableSet<E> extends DelegatingSet<E>
-    with ChangeNotifier<SetChangeRecord<E>>
-    implements ObservableSet<E> {
-  _DelegatingObservableSet(Set<E> set) : super(set);
-
-  @override
-  bool add(E value) {
-    if (super.add(value)) {
-      if (hasObservers) {
-        notifyChange(new SetChangeRecord<E>.add(value));
-      }
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  void addAll(Iterable<E> values) {
-    values.forEach(add);
-  }
-
-  @override
-  bool remove(Object value) {
-    if (super.remove(value)) {
-      if (hasObservers) {
-        notifyChange(new SetChangeRecord<E>.remove(value as E));
-      }
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  void removeAll(Iterable<Object> values) {
-    values.toList().forEach(remove);
-  }
-
-  @override
-  void removeWhere(bool test(E value)) {
-    removeAll(super.where(test));
-  }
-
-  @override
-  void retainAll(Iterable<Object> elements) {
-    retainWhere(elements.toSet().contains);
-  }
-
-  @override
-  void retainWhere(bool test(E element)) {
-    removeWhere((e) => !test(e));
-  }
-}
-
-class _UnmodifiableEmptySet<E> extends IterableBase<E> implements Set<E> {
-  const _UnmodifiableEmptySet();
-
-  @override
-  bool add(E value) => false;
-
-  @override
-  void addAll(Iterable<E> elements) {}
-
-  @override
-  void clear() {}
-
-  @override
-  bool containsAll(Iterable<Object> other) => other.isEmpty;
-
-  @override
-  Set<E> difference(Set<Object> other) => other.toSet();
-
-  @override
-  Set<E> intersection(Set<Object> other) => this;
-
-  @override
-  Iterator<E> get iterator => const <Null>[].iterator;
-
-  @override
-  E lookup(Object object) => null;
-
-  @override
-  bool remove(Object value) => false;
-
-  @override
-  void removeAll(Iterable<Object> elements) {}
-
-  @override
-  void removeWhere(bool test(E element)) {}
-
-  @override
-  void retainAll(Iterable<Object> elements) {}
-
-  @override
-  void retainWhere(bool test(E element)) {}
-
-  @override
-  Set<E> union(Set<E> other) => other.toSet();
-}
-
-class _UnmodifiableObservableSet<E> extends DelegatingSet<E>
-    implements ObservableSet<E> {
-  const _UnmodifiableObservableSet(Set<E> set) : super(set);
-
-  @override
-  Stream<List<SetChangeRecord<E>>> get changes => const Stream.empty();
-
-  @override
-  bool deliverChanges() => false;
-
-  // TODO: implement hasObservers
-  @override
-  final bool hasObservers = false;
-
-  @override
-  void notifyChange([ChangeRecord change]) {
-    throw new UnsupportedError('Not modifiable');
-  }
-
-  @override
-  T notifyPropertyChange<T>(
-    Symbol field,
-    T oldValue,
-    T newValue,
-  ) {
-    throw new UnsupportedError('Not modifiable');
-  }
-
-  @override
-  void observed() {}
-
-  @override
-  void unobserved() {}
-}
diff --git a/lib/src/differs.dart b/lib/src/differs.dart
index 63d5638..40f005e 100644
--- a/lib/src/differs.dart
+++ b/lib/src/differs.dart
@@ -9,11 +9,11 @@
 import 'package:collection/collection.dart';
 
 import 'records.dart';
+
 import 'internal.dart';
 
 part 'differs/list_differ.dart';
 part 'differs/map_differ.dart';
-part 'differs/set_differ.dart';
 
 /// Generic comparisons between two comparable objects.
 abstract class Differ<E> {
diff --git a/lib/src/differs/list_differ.dart b/lib/src/differs/list_differ.dart
index ab0e5c2..c59830e 100644
--- a/lib/src/differs/list_differ.dart
+++ b/lib/src/differs/list_differ.dart
@@ -206,7 +206,7 @@
   oldEnd -= suffixCount;
 
   if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) {
-    return ListChangeRecord.NONE;
+    return const [];
   }
 
   if (currentStart == currentEnd) {
@@ -440,10 +440,9 @@
 // If someone processed these records naively, they would "play back" the
 // insert incorrectly, because those items will be shifted.
 List<ListChangeRecord<E>> projectListSplices<E>(
-  List<E> list,
-  List<ListChangeRecord<E>> records, [
-  Equality<E> equality = const DefaultEquality(),
-]) {
+    List<E> list, List<ListChangeRecord<E>> records,
+    [Equality<E> equality]) {
+  equality ??= new DefaultEquality<E>();
   if (records.length <= 1) return records;
   final splices = <ListChangeRecord<E>>[];
   final initialSplices = _createInitialSplices(list, records);
diff --git a/lib/src/differs/map_differ.dart b/lib/src/differs/map_differ.dart
index 146834e..6f01fb7 100644
--- a/lib/src/differs/map_differ.dart
+++ b/lib/src/differs/map_differ.dart
@@ -17,7 +17,7 @@
   @override
   List<MapChangeRecord<K, V>> diff(Map<K, V> oldValue, Map<K, V> newValue) {
     if (identical(oldValue, newValue)) {
-      return MapChangeRecord.NONE;
+      return const [];
     }
     final changes = <MapChangeRecord<K, V>>[];
     oldValue.forEach((oldK, oldV) {
diff --git a/lib/src/differs/set_differ.dart b/lib/src/differs/set_differ.dart
deleted file mode 100644
index 31d93cb..0000000
--- a/lib/src/differs/set_differ.dart
+++ /dev/null
@@ -1,31 +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.
-
-part of observable.src.differs;
-
-/// Determines differences between two maps, returning [SetChangeRecord]s.
-///
-/// While [SetChangeRecord] has more information and can be replayed they carry
-/// a more significant cost to calculate and create and should only be used when
-/// the details in the record will actually be used.
-///
-/// See also [EqualityDiffer] for a simpler comparison.
-class SetDiffer<E> implements Differ<Set<E>> {
-  const SetDiffer();
-
-  @override
-  List<SetChangeRecord<E>> diff(Set<E> oldValue, Set<E> newValue) {
-    if (identical(oldValue, newValue)) {
-      return ChangeRecord.NONE;
-    }
-    final changes = <SetChangeRecord<E>>[];
-    for (final added in newValue.difference(oldValue)) {
-      changes.add(new SetChangeRecord<E>.add(added));
-    }
-    for (final removed in oldValue.difference(newValue)) {
-      changes.add(new SetChangeRecord<E>.remove(removed));
-    }
-    return changes;
-  }
-}
diff --git a/lib/src/observable.dart b/lib/src/observable.dart
index 1688202..edc536b 100644
--- a/lib/src/observable.dart
+++ b/lib/src/observable.dart
@@ -22,7 +22,7 @@
   final ChangeNotifier<C> _delegate = new ChangeNotifier<C>();
 
   // Whether Observable was not given a type.
-  final bool _supportsPropertyChanges = PropertyChangeRecord is C;
+  final bool _isNotGeneric = C == dynamic || C == ChangeRecord;
 
   /// Emits a list of changes when the state of the object changes.
   ///
@@ -53,6 +53,8 @@
   ///
   /// Returns `true` if changes were emitted.
   @Deprecated('Use ChangeNotifier instead to have this method available')
+  // REMOVE IGNORE when https://github.com/dart-lang/observable/issues/10
+  // ignore: invalid_use_of_protected_member
   bool deliverChanges() => _delegate.deliverChanges();
 
   /// Notify that the [field] name of this object has been changed.
@@ -76,15 +78,21 @@
     T oldValue,
     T newValue,
   ) {
-    if (hasObservers && oldValue != newValue && _supportsPropertyChanges) {
-      notifyChange(
-        new PropertyChangeRecord(
-          this,
-          field,
-          oldValue,
-          newValue,
-        ) as C,
-      );
+    if (hasObservers && oldValue != newValue) {
+      if (_isNotGeneric) {
+        notifyChange(
+          new PropertyChangeRecord(
+            this,
+            field,
+            oldValue,
+            newValue,
+          ) as C,
+        );
+      } else {
+        // Internal specific patch: Just do nothing.
+        //
+        // Generic typed Observable does not support.
+      }
     }
     return newValue;
   }
diff --git a/lib/src/observable_list.dart b/lib/src/observable_list.dart
new file mode 100644
index 0000000..2549f9b
--- /dev/null
+++ b/lib/src/observable_list.dart
@@ -0,0 +1,332 @@
+// 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<E>> _listRecords;
+
+  StreamController<List<ListChangeRecord<E>>> _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<E>>> 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<E> removed: const [],
+    int addedCount: 0,
+  }) {
+    if (!hasListObservers) return;
+    if (_listRecords == null) {
+      _listRecords = [];
+      scheduleMicrotask(deliverListChanges);
+    }
+    _listRecords.add(new ListChangeRecord<E>(
+      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;
+    final records = projectListSplices<E>(this, _listRecords);
+    _listRecords = null;
+
+    if (hasListObservers && records.isNotEmpty) {
+      _listChanges.add(new UnmodifiableListView<ListChangeRecord<E>>(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 new 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/observable_map.dart b/lib/src/observable_map.dart
new file mode 100644
index 0000000..7f28e20
--- /dev/null
+++ b/lib/src/observable_map.dart
@@ -0,0 +1,229 @@
+// 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_map;
+
+import 'dart:collection';
+
+import 'observable.dart';
+import 'records.dart';
+import 'to_observable.dart';
+
+// TODO(jmesserly): this needs to be faster. We currently require multiple
+// lookups per key to get the old value.
+// TODO(jmesserly): this doesn't implement the precise interfaces like
+// LinkedHashMap, SplayTreeMap or HashMap. However it can use them for the
+// backing store.
+
+/// Represents an observable map of model values. If any items are added,
+/// removed, or replaced, then observers that are listening to [changes]
+/// will be notified.
+class ObservableMap<K, V> extends Observable implements Map<K, V> {
+  final Map<K, V> _map;
+
+  /// Creates an observable map.
+  ObservableMap() : _map = new HashMap<K, V>();
+
+  /// Creates a new observable map using a [LinkedHashMap].
+  ObservableMap.linked() : _map = new LinkedHashMap<K, V>();
+
+  /// Creates a new observable map using a [SplayTreeMap].
+  ObservableMap.sorted() : _map = new SplayTreeMap<K, V>();
+
+  /// Creates an observable map that contains all key value pairs of [other].
+  /// It will attempt to use the same backing map type if the other map is a
+  /// [LinkedHashMap], [SplayTreeMap], or [HashMap]. Otherwise it defaults to
+  /// [HashMap].
+  ///
+  /// Note this will perform a shallow conversion. If you want a deep conversion
+  /// you should use [toObservable].
+  factory ObservableMap.from(Map<K, V> other) {
+    return new ObservableMap<K, V>.createFromType(other)..addAll(other);
+  }
+
+  /// Like [ObservableMap.from], but creates an empty map.
+  factory ObservableMap.createFromType(Map<K, V> other) {
+    ObservableMap<K, V> result;
+    if (other is SplayTreeMap) {
+      result = new ObservableMap<K, V>.sorted();
+    } else if (other is LinkedHashMap) {
+      result = new ObservableMap<K, V>.linked();
+    } else {
+      result = new ObservableMap<K, V>();
+    }
+    return result;
+  }
+
+  /// Creates a new observable map wrapping [other].
+  ObservableMap.spy(Map<K, V> other) : _map = other;
+
+  @override
+  Iterable<K> get keys => _map.keys;
+
+  @override
+  Iterable<V> get values => _map.values;
+
+  @override
+  int get length => _map.length;
+
+  @override
+  bool get isEmpty => length == 0;
+
+  @override
+  bool get isNotEmpty => !isEmpty;
+
+  @override
+  bool containsValue(Object value) => _map.containsValue(value);
+
+  @override
+  bool containsKey(Object key) => _map.containsKey(key);
+
+  @override
+  V operator [](Object key) => _map[key];
+
+  @override
+  void operator []=(K key, V value) {
+    if (!hasObservers) {
+      _map[key] = value;
+      return;
+    }
+
+    int len = _map.length;
+    V oldValue = _map[key];
+
+    _map[key] = value;
+
+    if (len != _map.length) {
+      notifyPropertyChange(#length, len, _map.length);
+      notifyChange(new MapChangeRecord.insert(key, value));
+      _notifyKeysValuesChanged();
+    } else if (oldValue != value) {
+      notifyChange(new MapChangeRecord(key, oldValue, value));
+      _notifyValuesChanged();
+    }
+  }
+
+  @override
+  void addAll(Map<K, V> other) {
+    other.forEach((K key, V value) {
+      this[key] = value;
+    });
+  }
+
+  @override
+  V putIfAbsent(K key, V ifAbsent()) {
+    int len = _map.length;
+    V result = _map.putIfAbsent(key, ifAbsent);
+    if (hasObservers && len != _map.length) {
+      notifyPropertyChange(#length, len, _map.length);
+      notifyChange(new MapChangeRecord.insert(key, result));
+      _notifyKeysValuesChanged();
+    }
+    return result;
+  }
+
+  @override
+  V remove(Object key) {
+    int len = _map.length;
+    V result = _map.remove(key);
+    if (hasObservers && len != _map.length) {
+      notifyChange(new MapChangeRecord.remove(key, result));
+      notifyPropertyChange(#length, len, _map.length);
+      _notifyKeysValuesChanged();
+    }
+    return result;
+  }
+
+  @override
+  void clear() {
+    int len = _map.length;
+    if (hasObservers && len > 0) {
+      _map.forEach((key, value) {
+        notifyChange(new MapChangeRecord.remove(key, value));
+      });
+      notifyPropertyChange(#length, len, 0);
+      _notifyKeysValuesChanged();
+    }
+    _map.clear();
+  }
+
+  @override
+  void forEach(void f(K key, V value)) => _map.forEach(f);
+
+  @override
+  String toString() => Maps.mapToString(this);
+
+  @override
+  // TODO: Dart 2.0 requires this method to be implemented.
+  // ignore: override_on_non_overriding_method
+  Map<K2, V2> cast<K2, V2>() {
+    throw new UnimplementedError("cast");
+  }
+
+  @override
+  // TODO: Dart 2.0 requires this method to be implemented.
+  // ignore: override_on_non_overriding_method
+  Map<K2, V2> retype<K2, V2>() {
+    throw new UnimplementedError("retype");
+  }
+
+  @override
+  // TODO: Dart 2.0 requires this method to be implemented.
+  // ignore: override_on_non_overriding_getter
+  Iterable<Null> get entries {
+    // Change Iterable<Null> to Iterable<MapEntry<K, V>> when
+    // the MapEntry class has been added.
+    throw new UnimplementedError("entries");
+  }
+
+  @override
+  // TODO: Dart 2.0 requires this method to be implemented.
+  // ignore: override_on_non_overriding_method
+  void addEntries(Iterable<Object> entries) {
+    // Change Iterable<Object> to Iterable<MapEntry<K, V>> when
+    // the MapEntry class has been added.
+    throw new UnimplementedError("addEntries");
+  }
+
+  @override
+  // TODO: Dart 2.0 requires this method to be implemented.
+  // ignore: override_on_non_overriding_method
+  Map<K2, V2> map<K2, V2>(Object transform(K key, V value)) {
+    // Change Object to MapEntry<K2, V2> when
+    // the MapEntry class has been added.
+    throw new UnimplementedError("map");
+  }
+
+  @override
+  // TODO: Dart 2.0 requires this method to be implemented.
+  // ignore: override_on_non_overriding_method
+  V update(K key, V update(V value), {V ifAbsent()}) {
+    throw new UnimplementedError("update");
+  }
+
+  @override
+  // TODO: Dart 2.0 requires this method to be implemented.
+  // ignore: override_on_non_overriding_method
+  void updateAll(V update(K key, V value)) {
+    throw new UnimplementedError("updateAll");
+  }
+
+  @override
+  // TODO: Dart 2.0 requires this method to be implemented.
+  // ignore: override_on_non_overriding_method
+  void removeWhere(bool test(K key, V value)) {
+    throw new UnimplementedError("removeWhere");
+  }
+
+  // Note: we don't really have a reasonable old/new value to use here.
+  // But this should fix "keys" and "values" in templates with minimal overhead.
+  void _notifyKeysValuesChanged() {
+    notifyChange(new PropertyChangeRecord(this, #keys, null, null));
+    _notifyValuesChanged();
+  }
+
+  void _notifyValuesChanged() {
+    notifyChange(new PropertyChangeRecord(this, #values, null, null));
+  }
+}
diff --git a/lib/src/records.dart b/lib/src/records.dart
index 6e5342b..87d7d4f 100644
--- a/lib/src/records.dart
+++ b/lib/src/records.dart
@@ -5,14 +5,13 @@
 library observable.src.records;
 
 import 'package:collection/collection.dart';
-import 'package:quiver/core.dart' as quiver;
+import 'package:quiver/core.dart';
 
 import 'internal.dart';
 
 part 'records/list_change_record.dart';
 part 'records/map_change_record.dart';
 part 'records/property_change_record.dart';
-part 'records/set_change_record.dart';
 
 /// Result of a change to an observed object.
 class ChangeRecord {
diff --git a/lib/src/records/list_change_record.dart b/lib/src/records/list_change_record.dart
index 0ebdb43..810843c 100644
--- a/lib/src/records/list_change_record.dart
+++ b/lib/src/records/list_change_record.dart
@@ -12,9 +12,6 @@
 /// the final list positions to figure out which item was added - this removes
 /// the need to incur costly GC on the most common operation (adding).
 class ListChangeRecord<E> implements ChangeRecord {
-  /// Signifies no changes occurred.
-  static const NONE = const <ListChangeRecord>[];
-
   /// How many elements were added at [index] (after removing elements).
   final int addedCount;
 
@@ -70,7 +67,9 @@
 
   /// What elements were added to [object].
   Iterable<E> get added {
-    return addedCount == 0 ? const [] : object.getRange(index, addedCount);
+    return addedCount == 0
+        ? const []
+        : object.getRange(index, index + addedCount);
   }
 
   /// Apply this change record to [list].
@@ -123,8 +122,7 @@
 
   @override
   int get hashCode {
-    return quiver.hash4(
-        object, index, addedCount, const ListEquality().hash(removed));
+    return hash4(object, index, addedCount, const ListEquality().hash(removed));
   }
 
   @override
diff --git a/lib/src/records/map_change_record.dart b/lib/src/records/map_change_record.dart
index 6c61115..cd37fc9 100644
--- a/lib/src/records/map_change_record.dart
+++ b/lib/src/records/map_change_record.dart
@@ -6,9 +6,6 @@
 
 /// A [ChangeRecord] that denotes adding, removing, or updating a map.
 class MapChangeRecord<K, V> implements ChangeRecord {
-  /// Signifies no changes occurred.
-  static const NONE = const <MapChangeRecord>[];
-
   /// The map key that changed.
   final K key;
 
@@ -68,7 +65,7 @@
 
   @override
   int get hashCode {
-    return quiver.hashObjects([
+    return hashObjects([
       key,
       oldValue,
       newValue,
@@ -80,6 +77,6 @@
   @override
   String toString() {
     final kind = isInsert ? 'insert' : isRemove ? 'remove' : 'set';
-    return '#<MapChangeRecord $kind $key from $oldValue to $newValue>';
+    return '#<MapChangeRecord $kind $key from $oldValue to $newValue';
   }
 }
diff --git a/lib/src/records/property_change_record.dart b/lib/src/records/property_change_record.dart
index e42077f..74566d5 100644
--- a/lib/src/records/property_change_record.dart
+++ b/lib/src/records/property_change_record.dart
@@ -26,20 +26,6 @@
   );
 
   @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 => quiver.hash4(object, name, oldValue, newValue);
-
-  @override
   String toString() => ''
       '#<$PropertyChangeRecord $name from $oldValue to: $newValue';
 }
diff --git a/lib/src/records/set_change_record.dart b/lib/src/records/set_change_record.dart
deleted file mode 100644
index ea09f60..0000000
--- a/lib/src/records/set_change_record.dart
+++ /dev/null
@@ -1,41 +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.
-
-part of observable.src.records;
-
-/// A [ChangeRecord] that denotes adding or removing values from a [Set].
-class SetChangeRecord<E> implements ChangeRecord {
-  /// Whether this is a removal operation.
-  final bool isRemove;
-
-  /// Element added or removed in the operation.
-  final E element;
-
-  const SetChangeRecord.add(this.element) : isRemove = false;
-  const SetChangeRecord.remove(this.element) : isRemove = true;
-
-  /// Whether this is an add operation.
-  bool get isAdd => !isRemove;
-
-  /// Apply the change operation to [set].
-  void apply(Set<E> set) {
-    if (isRemove) {
-      set.remove(element);
-    } else {
-      set.add(element);
-    }
-  }
-
-  @override
-  bool operator ==(Object o) =>
-      o is SetChangeRecord<E> && element == o.element && isRemove == o.isRemove;
-
-  @override
-  int get hashCode => quiver.hash2(element, isRemove);
-
-  @override
-  String toString() {
-    return '#<SetChangeRecord ${isRemove ? 'remove' : 'add'} $element>';
-  }
-}
diff --git a/lib/src/to_observable.dart b/lib/src/to_observable.dart
index b4cdaf0..3bf24b6 100644
--- a/lib/src/to_observable.dart
+++ b/lib/src/to_observable.dart
@@ -7,7 +7,8 @@
 import 'dart:collection';
 
 import 'observable.dart' show Observable;
-import 'collections.dart' show ObservableList, ObservableMap;
+import 'observable_list.dart' show ObservableList;
+import 'observable_map.dart' show ObservableMap;
 
 /// Converts the [Iterable] or [Map] to an [ObservableList] or [ObservableMap],
 /// respectively. This is a convenience function to make it easier to convert
diff --git a/pubspec.yaml b/pubspec.yaml
index 64bf8bf..868e3c8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,13 +1,14 @@
 name: observable
-version: 0.20.4+3
+version: 0.21.0
 author: Dart Team <misc@dartlang.org>
 description: Support for marking objects as observable
 homepage: https://github.com/dart-lang/observable
 environment:
-  sdk: '>=1.22.0 <2.0.0'
+  sdk: '>=2.0.0-dev.22.0 <2.0.0'
 dependencies:
-  collection: '^1.11.0'
-  meta: '^1.0.4'
-  quiver: '>=0.24.0 <0.28.0'
+  collection: '^1.14.5'
+  meta: '^1.1.2'
+  quiver: '^0.28.0'
 dev_dependencies:
-  test: '^0.12.17'
+  dart_style: '^1.0.9'
+  test: '^0.12.30'
diff --git a/test/collections/observable_list_test.dart b/test/collections/observable_list_test.dart
deleted file mode 100644
index 8cb9618..0000000
--- a/test/collections/observable_list_test.dart
+++ /dev/null
@@ -1,503 +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';
-
-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<ChangeRecord>> 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('listChanges stream', () {
-    Completer<List<ListChangeRecord>> completer;
-    ObservableList<String> list;
-    List<String> previousState;
-    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);
-      sub = list.listChanges.listen((c) {
-        if (completer?.isCompleted == false) {
-          completer.complete(c.toList());
-        }
-        previousState = list.toList();
-      });
-    });
-
-    tearDown(() => sub.cancel());
-
-    test('updates when an index changes', () async {
-      list[0] = 'd';
-      await expectChanges([
-        new ListChangeRecord.replace(list, 0, ['a']),
-      ]);
-    });
-
-    test('should not emit an empty list', () async {
-      // This is optimized into a no-op.
-      list[0] = 'd';
-      list[0] = 'a';
-      next().then((_) {
-        fail('Should not emit change records');
-      });
-      await new Future.value();
-    });
-  });
-
-  group('length changes', () {
-    Completer<List<ChangeRecord>> 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/collections/observable_set_test.dart b/test/collections/observable_set_test.dart
deleted file mode 100644
index 852fd17..0000000
--- a/test/collections/observable_set_test.dart
+++ /dev/null
@@ -1,163 +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';
-
-main() {
-  group('$ObservableSet', () {
-    group('set api', _runSetTests);
-    _runObservableSetTests();
-  });
-}
-
-_runSetTests() {
-  // TODO(matanl): Can we run the Set-API tests from the SDK?
-  // Any methods actually implemented by ObservableSet are below, otherwise I am
-  // relying on the test suite for DelegatingSet.
-  test('add', () {
-    final set = new ObservableSet<String>();
-    expect(set.add('item'), isTrue);
-    expect(set, ['item']);
-    expect(set.add('item'), isFalse);
-    expect(set, ['item']);
-  });
-
-  test('addAll', () {
-    final set = new ObservableSet<String>.linked();
-    set.addAll(['1', '2', '3']);
-    expect(set, ['1', '2', '3']);
-    set.addAll(['3', '4']);
-    expect(set, ['1', '2', '3', '4']);
-  });
-
-  test('remove', () {
-    final set = new ObservableSet<String>();
-    expect(set.remove('item'), isFalse);
-    expect(set, isEmpty);
-    set.add('item');
-    expect(set, isNotEmpty);
-    expect(set.remove('item'), isTrue);
-    expect(set, isEmpty);
-  });
-
-  test('removeAll', () {
-    final set = new ObservableSet<String>.from(['1', '2', '3']);
-    set.removeAll(['1', '3']);
-    expect(set, ['2']);
-  });
-
-  test('removeWhere', () {
-    final set = new ObservableSet<String>.from(['1', '2', '3']);
-    set.removeWhere((s) => s != '2');
-    expect(set, ['2']);
-  });
-
-  test('retainAll', () {
-    final set = new ObservableSet<String>.from(['1', '2', '3']);
-    set.retainAll(['2']);
-    expect(set, ['2']);
-  });
-
-  test('retainWhere', () {
-    final set = new ObservableSet<String>.from(['1', '2', '3']);
-    set.retainWhere((s) => s == '2');
-    expect(set, ['2']);
-  });
-}
-
-_runObservableSetTests() {
-  group('observable changes', () {
-    Completer<List<SetChangeRecord>> completer;
-    Set<String> previousState;
-
-    ObservableSet<String> set;
-    StreamSubscription sub;
-
-    Future next() {
-      completer = new Completer<List<SetChangeRecord>>.sync();
-      return completer.future;
-    }
-
-    Future<Null> expectChanges(List<SetChangeRecord> changes) {
-      // Applying these change records in order should make the new list.
-      for (final change in changes) {
-        change.apply(previousState);
-      }
-
-      expect(set, previousState);
-
-      // If these fail, it might be safe to update if optimized/changed.
-      return next().then((actualChanges) {
-        for (final change in changes) {
-          expect(actualChanges, contains(change));
-        }
-      });
-    }
-
-    setUp(() {
-      set = new ObservableSet.from(['a', 'b', 'c']);
-      previousState = set.toSet();
-      sub = set.changes.listen((c) {
-        if (completer?.isCompleted == false) {
-          completer.complete(c);
-        }
-        previousState = set.toSet();
-      });
-    });
-
-    tearDown(() => sub.cancel());
-
-    test('add', () async {
-      set.add('value');
-      await expectChanges([
-        new SetChangeRecord.add('value'),
-      ]);
-    });
-
-    test('addAll', () async {
-      set.addAll(['1', '2']);
-      await expectChanges([
-        new SetChangeRecord.add('1'),
-        new SetChangeRecord.add('2'),
-      ]);
-    });
-
-    test('remove', () async {
-      set.remove('a');
-      await expectChanges([
-        new SetChangeRecord.remove('a'),
-      ]);
-    });
-
-    Future expectOnlyItem() {
-      return expectChanges([
-        new SetChangeRecord.remove('a'),
-        new SetChangeRecord.remove('c'),
-      ]);
-    }
-
-    test('removeAll', () async {
-      set.removeAll(['a', 'c']);
-      await expectOnlyItem();
-    });
-
-    test('removeWhere', () async {
-      set.removeWhere((s) => s != 'b');
-      await expectOnlyItem();
-    });
-
-    test('retainAll', () async {
-      set.retainAll(['b']);
-      await expectOnlyItem();
-    });
-
-    test('retainWhere', () async {
-      set.retainWhere((s) => s == 'b');
-      await expectOnlyItem();
-    });
-  });
-}
diff --git a/test/differs/set_differ_test.dart b/test/differs/set_differ_test.dart
deleted file mode 100644
index b6fbf04..0000000
--- a/test/differs/set_differ_test.dart
+++ /dev/null
@@ -1,69 +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 'package:observable/observable.dart';
-import 'package:test/test.dart';
-
-main() {
-  group('$SetDiffer', () {
-    final diff = const SetDiffer<String>().diff;
-
-    test('should emit no changes for identical maps', () {
-      final set = new Set<String>.from(
-        new Iterable.generate(10, (i) => '$i'),
-      );
-      expect(diff(set, set), ChangeRecord.NONE);
-    });
-
-    test('should emit no changes for maps with identical content', () {
-      final set1 = new Set<String>.from(
-        new Iterable.generate(10, (i) => '$i'),
-      );
-      final set2 = new Set<String>.from(
-        new Iterable.generate(10, (i) => '$i'),
-      );
-      expect(diff(set1, set2), ChangeRecord.NONE);
-    });
-
-    test('should detect insertions', () {
-      expect(
-        diff(
-          new Set<String>.from(['a']),
-          new Set<String>.from(['a', 'b']),
-        ),
-        [
-          new SetChangeRecord.add('b'),
-        ],
-      );
-    });
-
-    test('should detect removals', () {
-      expect(
-        diff(
-          new Set<String>.from(['a', 'b']),
-          new Set<String>.from(['a']),
-        ),
-        [
-          new SetChangeRecord.remove('b'),
-        ],
-      );
-    });
-  });
-
-  group('$SetChangeRecord', () {
-    test('should reply an insertion', () {
-      final set1 = new Set<String>.from(['a', 'b']);
-      final set2 = new Set<String>.from(['a', 'b', 'c']);
-      new SetChangeRecord.add('c').apply(set1);
-      expect(set1, set2);
-    });
-
-    test('should replay a removal', () {
-      final set1 = new Set<String>.from(['a', 'b', 'c']);
-      final set2 = new Set<String>.from(['a', 'b']);
-      new SetChangeRecord.remove('c').apply(set1);
-      expect(set1, set2);
-    });
-  });
-}
diff --git a/test/list_change_test.dart b/test/list_change_test.dart
index cf2ac53..8560688 100644
--- a/test/list_change_test.dart
+++ b/test/list_change_test.dart
@@ -12,19 +12,21 @@
 // This file contains code ported from:
 // https://github.com/rafaelw/ChangeSummary/blob/master/tests/test.js
 
-// TODO(jmesserly): port or write array fuzzer tests
-void main() {
-  StreamSubscription sub;
-  ObservableList model;
+main() => listChangeTests();
 
-  tearDown(() async {
-    await sub?.cancel();
+// TODO(jmesserly): port or write array fuzzer tests
+listChangeTests() {
+  StreamSubscription sub;
+  var model;
+
+  tearDown(() {
+    sub?.cancel();
     model = null;
   });
 
   _delta(i, r, a) => new ListChangeRecord(model, i, removed: r, addedCount: a);
 
-  test('sequential adds', () async {
+  test('sequential adds', () {
     model = toObservable([]);
     model.add(0);
 
@@ -35,42 +37,46 @@
     model.add(2);
 
     expect(summary, null);
-    await newMicrotask();
-    expectChanges(summary, [_delta(1, [], 2)]);
+    return new Future(() {
+      expectChanges(summary, [_delta(1, [], 2)]);
+      expect(summary[0].added, [1, 2]);
+      expect(summary[0].removed, []);
+    });
   });
 
-  test('List Splice Truncate And Expand With Length', () async {
+  test('List Splice Truncate And Expand With Length', () {
     model = toObservable(['a', 'b', 'c', 'd', 'e']);
 
     var summary;
     sub = model.listChanges.listen((r) => summary = r);
 
     model.length = 2;
-
-    await newMicrotask();
-    expectChanges(summary, [
-      _delta(2, ['c', 'd', 'e'], 0)
-    ]);
-    summary = null;
-    model.length = 5;
-
-    await newMicrotask();
-
-    expectChanges(summary, [_delta(2, [], 3)]);
+    return new Future(() {
+      expectChanges(summary, [
+        _delta(2, ['c', 'd', 'e'], 0)
+      ]);
+      expect(summary[0].added, []);
+      expect(summary[0].removed, ['c', 'd', 'e']);
+      summary = null;
+      model.length = 5;
+    }).then(newMicrotask).then((_) {
+      expectChanges(summary, [_delta(2, [], 3)]);
+      expect(summary[0].added, [null, null, null]);
+      expect(summary[0].removed, []);
+    });
   });
 
   group('List deltas can be applied', () {
-    Future applyAndCheckDeltas(model, copy, Future changes) async {
-      var summary = await changes;
-      // apply deltas to the copy
-      for (ListChangeRecord delta in summary) {
-        delta.apply(copy);
-      }
+    applyAndCheckDeltas(model, copy, changes) => changes.then((summary) {
+          // apply deltas to the copy
+          for (ListChangeRecord delta in summary) {
+            delta.apply(copy);
+          }
 
-      expect('$copy', '$model', reason: 'summary $summary');
-    }
+          expect('$copy', '$model', reason: 'summary $summary');
+        });
 
-    test('Contained', () async {
+    test('Contained', () {
       var model = toObservable(['a', 'b']);
       var copy = model.toList();
       var changes = model.listChanges.first;
@@ -80,10 +86,10 @@
       model.removeRange(1, 3);
       model.insert(1, 'f');
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
 
-    test('Delete Empty', () async {
+    test('Delete Empty', () {
       var model = toObservable([1]);
       var copy = model.toList();
       var changes = model.listChanges.first;
@@ -91,10 +97,10 @@
       model.removeAt(0);
       model.insertAll(0, ['a', 'b', 'c']);
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
 
-    test('Right Non Overlap', () async {
+    test('Right Non Overlap', () {
       var model = toObservable(['a', 'b', 'c', 'd']);
       var copy = model.toList();
       var changes = model.listChanges.first;
@@ -104,10 +110,10 @@
       model.removeRange(2, 3);
       model.insertAll(2, ['f', 'g']);
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
 
-    test('Left Non Overlap', () async {
+    test('Left Non Overlap', () {
       var model = toObservable(['a', 'b', 'c', 'd']);
       var copy = model.toList();
       var changes = model.listChanges.first;
@@ -117,10 +123,10 @@
       model.removeRange(0, 1);
       model.insert(0, 'e');
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
 
-    test('Right Adjacent', () async {
+    test('Right Adjacent', () {
       var model = toObservable(['a', 'b', 'c', 'd']);
       var copy = model.toList();
       var changes = model.listChanges.first;
@@ -130,10 +136,10 @@
       model.removeRange(2, 3);
       model.insertAll(0, ['f', 'g']);
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
 
-    test('Left Adjacent', () async {
+    test('Left Adjacent', () {
       var model = toObservable(['a', 'b', 'c', 'd']);
       var copy = model.toList();
       var changes = model.listChanges.first;
@@ -144,10 +150,10 @@
       model.removeAt(1);
       model.insertAll(1, ['f', 'g']);
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
 
-    test('Right Overlap', () async {
+    test('Right Overlap', () {
       var model = toObservable(['a', 'b', 'c', 'd']);
       var copy = model.toList();
       var changes = model.listChanges.first;
@@ -157,10 +163,10 @@
       model.removeAt(1);
       model.insertAll(1, ['f', 'g']);
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
 
-    test('Left Overlap', () async {
+    test('Left Overlap', () {
       var model = toObservable(['a', 'b', 'c', 'd']);
       var copy = model.toList();
       var changes = model.listChanges.first;
@@ -172,10 +178,10 @@
       model.insertAll(1, ['h', 'i', 'j']);
       // a [h i j] f g d
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
 
-    test('Prefix And Suffix One In', () async {
+    test('Prefix And Suffix One In', () {
       var model = toObservable(['a', 'b', 'c', 'd']);
       var copy = model.toList();
       var changes = model.listChanges.first;
@@ -183,20 +189,20 @@
       model.insert(0, 'z');
       model.add('z');
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
 
-    test('Remove First', () async {
+    test('Remove First', () {
       var model = toObservable([16, 15, 15]);
       var copy = model.toList();
       var changes = model.listChanges.first;
 
       model.removeAt(0);
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
 
-    test('Update Remove', () async {
+    test('Update Remove', () {
       var model = toObservable(['a', 'b', 'c', 'd']);
       var copy = model.toList();
       var changes = model.listChanges.first;
@@ -206,61 +212,60 @@
       model[0] = 'h';
       model.removeAt(1);
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
 
-    test('Remove Mid List', () async {
+    test('Remove Mid List', () {
       var model = toObservable(['a', 'b', 'c', 'd']);
       var copy = model.toList();
       var changes = model.listChanges.first;
 
       model.removeAt(2);
 
-      await applyAndCheckDeltas(model, copy, changes);
+      return applyAndCheckDeltas(model, copy, changes);
     });
   });
 
   group('edit distance', () {
-    Future assertEditDistance(orig, Future changes, expectedDist) async {
-      var summary = await changes;
-      var actualDistance = 0;
-      for (var delta in summary) {
-        actualDistance += delta.addedCount + delta.removed.length;
-      }
+    assertEditDistance(orig, changes, expectedDist) => changes.then((summary) {
+          var actualDistance = 0;
+          for (var delta in summary) {
+            actualDistance += delta.addedCount + delta.removed.length;
+          }
 
-      expect(actualDistance, expectedDist);
-    }
+          expect(actualDistance, expectedDist);
+        });
 
-    test('add items', () async {
+    test('add items', () {
       var model = toObservable([]);
       var changes = model.listChanges.first;
       model.addAll([1, 2, 3]);
-      await assertEditDistance(model, changes, 3);
+      return assertEditDistance(model, changes, 3);
     });
 
-    test('trunacte and add, sharing a contiguous block', () async {
+    test('trunacte and add, sharing a contiguous block', () {
       var model = toObservable(['x', 'x', 'x', 'x', '1', '2', '3']);
       var changes = model.listChanges.first;
       model.length = 0;
       model.addAll(['1', '2', '3', 'y', 'y', 'y', 'y']);
-      await assertEditDistance(model, changes, 8);
+      return assertEditDistance(model, changes, 8);
     });
 
-    test('truncate and add, sharing a discontiguous block', () async {
+    test('truncate and add, sharing a discontiguous block', () {
       var model = toObservable(['1', '2', '3', '4', '5']);
       var changes = model.listChanges.first;
       model.length = 0;
       model.addAll(['a', '2', 'y', 'y', '4', '5', 'z', 'z']);
-      await assertEditDistance(model, changes, 7);
+      return assertEditDistance(model, changes, 7);
     });
 
-    test('insert at beginning and end', () async {
+    test('insert at beginning and end', () {
       var model = toObservable([2, 3, 4]);
       var changes = model.listChanges.first;
       model.insert(0, 5);
       model[2] = 6;
       model.add(7);
-      await assertEditDistance(model, changes, 4);
+      return assertEditDistance(model, changes, 4);
     });
   });
 }
diff --git a/test/differs/map_differ_test.dart b/test/map_differ_test.dart
similarity index 87%
rename from test/differs/map_differ_test.dart
rename to test/map_differ_test.dart
index 2875015..7fb9ca9 100644
--- a/test/differs/map_differ_test.dart
+++ b/test/map_differ_test.dart
@@ -1,7 +1,3 @@
-// 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 'package:observable/observable.dart';
 import 'package:test/test.dart';
 
@@ -13,7 +9,7 @@
       final map = new Map<String, String>.fromIterable(
         new Iterable.generate(10, (i) => '$i'),
       );
-      expect(diff(map, map), MapChangeRecord.NONE);
+      expect(diff(map, map), isEmpty);
     });
 
     test('should emit no changes for maps with identical content', () {
@@ -23,7 +19,7 @@
       final map2 = new Map<String, String>.fromIterable(
         new Iterable.generate(10, (i) => '$i'),
       );
-      expect(diff(map1, map2), MapChangeRecord.NONE);
+      expect(diff(map1, map2), isEmpty);
     });
 
     test('should detect insertions', () {
@@ -75,7 +71,7 @@
   });
 
   group('$MapChangeRecord', () {
-    test('should replay an insertion', () {
+    test('should reply an insertion', () {
       final map1 = {
         'key-a': 'value-a',
         'key-b': 'value-b',
diff --git a/test/observable_list_test.dart b/test/observable_list_test.dart
new file mode 100644
index 0000000..b999cfd
--- /dev/null
+++ b/test/observable_list_test.dart
@@ -0,0 +1,342 @@
+// 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<int> 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_map_test.dart b/test/observable_map_test.dart
index bddc091..04aeccc 100644
--- a/test/observable_map_test.dart
+++ b/test/observable_map_test.dart
@@ -9,7 +9,9 @@
 
 import 'observable_test_utils.dart';
 
-void main() {
+main() => _runTests();
+
+_runTests() {
   // TODO(jmesserly): need all standard Map API tests.
 
   StreamSubscription sub;
@@ -189,6 +191,79 @@
     expect(map.toString(), '{a: 1, b: 2}');
   });
 
+  group('observe keys/values', () {
+    ObservableMap map;
+    int keysChanged;
+    int valuesChanged;
+
+    setUp(() {
+      map = toObservable({'a': 1, 'b': 2, 'c': 3});
+      keysChanged = 0;
+      valuesChanged = 0;
+      sub = map.changes.listen((records) {
+        keysChanged += getPropertyChangeRecords(records, #keys).length;
+        valuesChanged += getPropertyChangeRecords(records, #values).length;
+      });
+    });
+
+    tearDown(sharedTearDown);
+
+    test('add item changes keys/values', () {
+      map['d'] = 4;
+      expect(map, {'a': 1, 'b': 2, 'c': 3, 'd': 4});
+      return new Future(() {
+        expect(keysChanged, 1);
+        expect(valuesChanged, 1);
+      });
+    });
+
+    test('putIfAbsent changes keys/values', () {
+      map.putIfAbsent('d', () => 4);
+      expect(map, {'a': 1, 'b': 2, 'c': 3, 'd': 4});
+      return new Future(() {
+        expect(keysChanged, 1);
+        expect(valuesChanged, 1);
+      });
+    });
+
+    test('remove changes keys/values', () {
+      map.remove('c');
+      map.remove('a');
+      expect(map, {'b': 2});
+      return new Future(() {
+        expect(keysChanged, 2);
+        expect(valuesChanged, 2);
+      });
+    });
+
+    test('remove non-existent item does not change keys/values', () {
+      map.remove('d');
+      expect(map, {'a': 1, 'b': 2, 'c': 3});
+      return new Future(() {
+        expect(keysChanged, 0);
+        expect(valuesChanged, 0);
+      });
+    });
+
+    test('set existing item does not change keys', () {
+      map['c'] = 9000;
+      expect(map, {'a': 1, 'b': 2, 'c': 9000});
+      return new Future(() {
+        expect(keysChanged, 0);
+        expect(valuesChanged, 1);
+      });
+    });
+
+    test('clear changes keys/values', () {
+      map.clear();
+      expect(map, {});
+      return new Future(() {
+        expect(keysChanged, 1);
+        expect(valuesChanged, 1);
+      });
+    });
+  });
+
   group('change records', () {
     List<ChangeRecord> records;
     ObservableMap map;
@@ -233,6 +308,8 @@
         expectChanges(records, [
           _lengthChange(map, 2, 3),
           _insertKey('c', 3),
+          _propChange(map, #keys),
+          _propChange(map, #values),
         ]);
       });
     });
@@ -247,8 +324,11 @@
       return new Future(() {
         expectChanges(records, [
           _changeKey('a', 1, 42),
+          _propChange(map, #values),
           _lengthChange(map, 2, 3),
           _insertKey('c', 3),
+          _propChange(map, #keys),
+          _propChange(map, #values),
         ]);
       });
     });
@@ -261,6 +341,8 @@
         expectChanges(records, [
           _removeKey('b', 2),
           _lengthChange(map, 2, 1),
+          _propChange(map, #keys),
+          _propChange(map, #values),
         ]);
       });
     });
@@ -274,6 +356,8 @@
           _removeKey('a', 1),
           _removeKey('b', 2),
           _lengthChange(map, 2, 0),
+          _propChange(map, #keys),
+          _propChange(map, #values),
         ]);
       });
     });
@@ -303,3 +387,5 @@
 _insertKey(key, newValue) => new MapChangeRecord.insert(key, newValue);
 
 _removeKey(key, oldValue) => new MapChangeRecord.remove(key, oldValue);
+
+_propChange(map, prop) => new PropertyChangeRecord(map, prop, null, null);
diff --git a/test/observable_test.dart b/test/observable_test.dart
index c902ba8..af4d9c3 100644
--- a/test/observable_test.dart
+++ b/test/observable_test.dart
@@ -9,16 +9,23 @@
 
 import 'observable_test_utils.dart';
 
-void main() {
+main() => observableTests();
+
+void observableTests() {
   // Track the subscriptions so we can clean them up in tearDown.
-  List<StreamSubscription> subs;
+  List subs;
 
   setUp(() {
-    subs = <StreamSubscription>[];
+    subs = [];
   });
 
-  tearDown(() async {
-    for (var sub in subs) await sub.cancel();
+  tearDown(() {
+    for (var sub in subs) sub.cancel();
+  });
+
+  test('handle future result', () {
+    var callback = expectAsync(() {});
+    return new Future(callback);
   });
 
   test('no observers', () {
@@ -41,7 +48,7 @@
     var t = createModel(123);
     int called = 0;
 
-    subs.add(t.changes.listen(expectAsync1((records) {
+    subs.add(t.changes.listen(expectAsync((records) {
       called++;
       expectPropertyChanges(records, 2);
     })));
@@ -55,7 +62,7 @@
     var t = createModel(123);
     int called = 0;
 
-    subs.add(t.changes.listen(expectAsync1((records) {
+    subs.add(t.changes.listen(expectAsync((records) {
       called++;
       expectPropertyChanges(records, 1);
       if (called == 1) {
@@ -74,14 +81,14 @@
       expectPropertyChanges(records, 2);
     }
 
-    subs.add(t.changes.listen(expectAsync1(verifyRecords)));
-    subs.add(t.changes.listen(expectAsync1(verifyRecords)));
+    subs.add(t.changes.listen(expectAsync(verifyRecords)));
+    subs.add(t.changes.listen(expectAsync(verifyRecords)));
 
     t.value = 41;
     t.value = 42;
   });
 
-  test('async processing model', () async {
+  test('async processing model', () {
     var t = createModel(123);
     var records = [];
     subs.add(t.changes.listen((r) {
@@ -91,22 +98,21 @@
     t.value = 42;
     expectChanges(records, [], reason: 'changes delived async');
 
-    await newMicrotask();
+    return new Future(() {
+      expectPropertyChanges(records, 2);
+      records.clear();
 
-    expectPropertyChanges(records, 2);
-    records.clear();
-
-    t.value = 777;
-    expectChanges(records, [], reason: 'changes delived async');
-
-    await newMicrotask();
-    expectPropertyChanges(records, 1);
+      t.value = 777;
+      expectChanges(records, [], reason: 'changes delived async');
+    }).then(newMicrotask).then((_) {
+      expectPropertyChanges(records, 1);
+    });
   });
 
   test('cancel listening', () {
     var t = createModel(123);
     var sub;
-    sub = t.changes.listen(expectAsync1((records) {
+    sub = t.changes.listen(expectAsync((records) {
       expectPropertyChanges(records, 1);
       sub.cancel();
       t.value = 777;
@@ -117,12 +123,12 @@
   test('cancel and reobserve', () {
     var t = createModel(123);
     var sub;
-    sub = t.changes.listen(expectAsync1((records) {
+    sub = t.changes.listen(expectAsync((records) {
       expectPropertyChanges(records, 1);
       sub.cancel();
 
       scheduleMicrotask(() {
-        subs.add(t.changes.listen(expectAsync1((records) {
+        subs.add(t.changes.listen(expectAsync((records) {
           expectPropertyChanges(records, 1);
         })));
         t.value = 777;
diff --git a/test/observable_test_utils.dart b/test/observable_test_utils.dart
index 91164c8..990cc86 100644
--- a/test/observable_test_utils.dart
+++ b/test/observable_test_utils.dart
@@ -13,13 +13,12 @@
 /// to happen in the next microtask:
 ///
 ///     future.then(newMicrotask).then(...)
-Future newMicrotask() => new Future.value();
+newMicrotask(_) => new Future.value();
 
 // 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) =>
