Fix Dart 2 runtime errors (#101)

Closes #100
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 41a060c..74928da 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.7.3
+
+* Fix some Dart 2 runtime errors.
+
 ## 0.7.2
 
 * Update `createMiddleware` arguments to use `FutureOr`.
diff --git a/lib/src/server_handler.dart b/lib/src/server_handler.dart
index 420ec17..db9efc7 100644
--- a/lib/src/server_handler.dart
+++ b/lib/src/server_handler.dart
@@ -8,6 +8,7 @@
 
 import 'handler.dart';
 import 'request.dart';
+import 'response.dart';
 import 'server.dart';
 
 /// A connected pair of a [Server] and a [Handler].
@@ -41,7 +42,7 @@
       : _server = new _HandlerServer(url, onClose);
 
   /// Pipes requests to [server]'s handler.
-  _onRequest(Request request) {
+  FutureOr<Response> _onRequest(Request request) {
     if (_server._closeMemo.hasRun) {
       throw new StateError("Request received after the server was closed.");
     }
diff --git a/lib/src/shelf_unmodifiable_map.dart b/lib/src/shelf_unmodifiable_map.dart
index 20eb20a..3e1d14f 100644
--- a/lib/src/shelf_unmodifiable_map.dart
+++ b/lib/src/shelf_unmodifiable_map.dart
@@ -55,4 +55,11 @@
     implements ShelfUnmodifiableMap<V> {
   bool get _ignoreKeyCase => true;
   const _EmptyShelfUnmodifiableMap() : super(const {});
+
+  // Override modifier methods that care about the type of key they use so that
+  // when V is Null, they throw UnsupportedErrors instead of type errors.
+  void operator []=(String key, Object value) => super[key] = null;
+  void addAll(Map<String, Object> other) => super.addAll({});
+  V putIfAbsent(String key, Object ifAbsent()) =>
+      super.putIfAbsent(key, () => null);
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index b61558f..d65e6bc 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: shelf
-version: 0.7.2
+version: 0.7.3
 author: Dart Team <misc@dartlang.org>
 description: Web Server Middleware for Dart
 homepage: https://github.com/dart-lang/shelf