Add implementations of Dart 2 methods. (#62)

* Add implementations of Dart 2 methods.

* Address review feedback.

* Prepare to release.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3a74d31..88e1ba3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.21.3
+
+* Support Dart 2 collection methods where previously threw `UnimplementedError`.
+
 ## 0.21.2
 
 * Fix `toObservable(deep: false)` to be shallow again.
diff --git a/lib/src/observable_map.dart b/lib/src/observable_map.dart
index a450fb3..4f43d13 100644
--- a/lib/src/observable_map.dart
+++ b/lib/src/observable_map.dart
@@ -155,66 +155,41 @@
   String toString() => MapBase.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");
+  ObservableMap<K2, V2> cast<K2, V2>() {
+    if (this is ObservableMap<K2, V2>) {
+      return this as ObservableMap<K2, V2>;
+    }
+    return new ObservableMap.createFromType(_map.cast<K2, V2>());
   }
 
   @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");
+  ObservableMap<K2, V2> retype<K2, V2>() {
+    return new ObservableMap.createFromType(_map.retype<K2, V2>());
   }
 
   @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");
+  Iterable<MapEntry<K, V>> get entries => _map.entries;
+
+  @override
+  void addEntries(Iterable<MapEntry<K, V>> entries) {
+    _map.addEntries(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");
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> transform(K key, V value)) {
+    return _map.map(transform);
   }
 
   @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");
+    return _map.update(key, update, ifAbsent: ifAbsent);
   }
 
   @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");
-  }
+  void updateAll(V update(K key, V value)) => _map.updateAll(update);
 
   @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");
-  }
+  void removeWhere(bool test(K key, V value)) => _map.removeWhere(test);
 
   // 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.
diff --git a/pubspec.yaml b/pubspec.yaml
index 7241145..4f1b31d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: observable
-version: 0.21.2
+version: 0.21.3
 author: Dart Team <misc@dartlang.org>
 description: Support for marking objects as observable
 homepage: https://github.com/dart-lang/observable