Fix all strong-mode warnings and errors.

R=kevmoo@google.com

Review URL: https://codereview.chromium.org//1950833002 .
diff --git a/.analysis_options b/.analysis_options
new file mode 100644
index 0000000..a10d4c5
--- /dev/null
+++ b/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+  strong-mode: true
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 37b00bf..e0c1f2e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.6.5+1
+
+* Fix all strong-mode warnings and errors.
+
 ## 0.6.5
 
 * `Request.hijack()` now takes a callback that accepts a single `StreamChannel`
diff --git a/lib/shelf_io.dart b/lib/shelf_io.dart
index af6780e..4991089 100644
--- a/lib/shelf_io.dart
+++ b/lib/shelf_io.dart
@@ -109,7 +109,7 @@
 
 /// Creates a new [Request] from the provided [HttpRequest].
 Request _fromHttpRequest(HttpRequest request) {
-  var headers = {};
+  var headers = <String, String>{};
   request.headers.forEach((k, v) {
     // Multiple header values are joined with commas.
     // See http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-21#page-22
diff --git a/lib/src/body.dart b/lib/src/body.dart
index 87e0483..6fd0df2 100644
--- a/lib/src/body.dart
+++ b/lib/src/body.dart
@@ -5,6 +5,8 @@
 import 'dart:async';
 import 'dart:convert';
 
+import 'package:async/async.dart';
+
 /// The body of a request or response.
 ///
 /// This tracks whether the body has been read. It's separate from [Message]
@@ -28,13 +30,13 @@
 
     if (body is Body) return body;
 
-    var stream;
+    Stream<List<int>> stream;
     if (body == null) {
       stream = new Stream.fromIterable([]);
     } else if (body is String) {
       stream = new Stream.fromIterable([encoding.encode(body)]);
     } else if (body is Stream) {
-      stream = body;
+      stream = DelegatingStream.typed(body);
     } else {
       throw new ArgumentError('Response body "$body" must be a String or a '
           'Stream.');
diff --git a/lib/src/cascade.dart b/lib/src/cascade.dart
index 412e7a3..1f3b167 100644
--- a/lib/src/cascade.dart
+++ b/lib/src/cascade.dart
@@ -80,8 +80,8 @@
 
 /// Computes the [Cascade._shouldCascade] function based on the user's
 /// parameters.
-Function _computeShouldCascade(
-    Iterable<int> statusCodes, Function shouldCascade) {
+_ShouldCascade _computeShouldCascade(Iterable<int> statusCodes,
+    bool shouldCascade(Response response)) {
   if (shouldCascade != null) return shouldCascade;
   if (statusCodes == null) statusCodes = [404, 405];
   statusCodes = statusCodes.toSet();
diff --git a/lib/src/request.dart b/lib/src/request.dart
index e0aa8ea..1b18418 100644
--- a/lib/src/request.dart
+++ b/lib/src/request.dart
@@ -246,14 +246,14 @@
       throw new StateError("This request can't be hijacked.");
     }
 
-    if (callback is! ZoneBinaryCallback) {
-      var oldCallback = callback;
-      callback = (stream, sink) {
-        oldCallback(new StreamChannel<List<int>>(stream, sink));
-      };
+    if (callback is HijackCallback) {
+      _onHijack.run(callback);
+    } else {
+      _onHijack.run((Stream<List<int>> stream, StreamSink<List<int>> sink) {
+        callback(new StreamChannel<List<int>>(stream, sink));
+      });
     }
 
-    _onHijack.run(callback);
     throw const HijackException();
   }
 }
diff --git a/lib/src/util.dart b/lib/src/util.dart
index 822395e..6fd62d6 100644
--- a/lib/src/util.dart
+++ b/lib/src/util.dart
@@ -28,7 +28,8 @@
 /// [updates] is used.
 ///
 /// If [updates] is `null` or empty, [original] is returned unchanged.
-Map updateMap(Map original, Map updates) {
+Map/*<K, V>*/ updateMap/*<K, V>*/(Map/*<K, V>*/ original,
+    Map/*<K, V>*/ updates) {
   if (updates == null || updates.isEmpty) return original;
 
   return new Map.from(original)..addAll(updates);
diff --git a/pubspec.yaml b/pubspec.yaml
index 6ab9930..f19b502 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,12 +1,12 @@
 name: shelf
-version: 0.6.6-dev
+version: 0.6.5+1
 author: Dart Team <misc@dartlang.org>
 description: Web Server Middleware for Dart
 homepage: https://github.com/dart-lang/shelf
 environment:
   sdk: '>=1.12.0 <2.0.0'
 dependencies:
-  async: '^1.3.0'
+  async: '^1.10.0'
   http_parser: '>=1.0.0 <3.0.0'
   path: '^1.0.0'
   stack_trace: '^1.0.0'
diff --git a/test/cascade_test.dart b/test/cascade_test.dart
index 6b1df62..d636cbd 100644
--- a/test/cascade_test.dart
+++ b/test/cascade_test.dart
@@ -11,7 +11,7 @@
 
 void main() {
   group('a cascade with several handlers', () {
-    var handler;
+    Handler handler;
     setUp(() {
       handler = new Cascade().add((request) {
         if (request.headers['one'] == 'false') {
@@ -34,11 +34,10 @@
       }).handler;
     });
 
-    test('the first response should be returned if it matches', () {
-      return makeSimpleRequest(handler).then((response) {
-        expect(response.statusCode, equals(200));
-        expect(response.readAsString(), completion(equals('handler 1')));
-      });
+    test('the first response should be returned if it matches', () async {
+      var response = await makeSimpleRequest(handler);
+      expect(response.statusCode, equals(200));
+      expect(response.readAsString(), completion(equals('handler 1')));
     });
 
     test("the second response should be returned if it matches and the first "
diff --git a/test/log_middleware_test.dart b/test/log_middleware_test.dart
index c7f448d..dd81e6b 100644
--- a/test/log_middleware_test.dart
+++ b/test/log_middleware_test.dart
@@ -14,7 +14,7 @@
     gotLog = false;
   });
 
-  var logger = (msg, isError) {
+  var logger = (String msg, bool isError) {
     expect(gotLog, isFalse);
     gotLog = true;
     expect(isError, isFalse);
diff --git a/test/shelf_io_test.dart b/test/shelf_io_test.dart
index ea8002e..3e644e5 100644
--- a/test/shelf_io_test.dart
+++ b/test/shelf_io_test.dart
@@ -253,7 +253,7 @@
   });
 
   test('a bad HTTP request results in a 500 response', () {
-    var socket;
+    Socket socket;
 
     _scheduleServer(syncHandler);
 
@@ -274,10 +274,9 @@
       return socket.close();
     });
 
-    schedule(() {
-      return UTF8.decodeStream(socket).then((value) {
-        expect(value, contains('500 Internal Server Error'));
-      });
+    schedule(() async {
+      expect(await UTF8.decodeStream(socket),
+          contains('500 Internal Server Error'));
     });
   });
 
@@ -337,7 +336,7 @@
   });
 
   test('respects the "shelf.io.buffer_output" context parameter', () {
-    var controller = new StreamController();
+    var controller = new StreamController<String>();
     _scheduleServer((request) {
       controller.add("Hello, ");
 
@@ -382,13 +381,13 @@
 Future<http.Response> _scheduleGet({Map<String, String> headers}) {
   if (headers == null) headers = {};
 
-  return schedule(
+  return schedule/*<Future<http.Response>>*/(
       () => http.get('http://localhost:$_serverPort/', headers: headers));
 }
 
 Future<http.StreamedResponse> _schedulePost(
     {Map<String, String> headers, String body}) {
-  return schedule(() {
+  return schedule/*<Future<http.StreamedResponse>>*/(() {
     var request =
         new http.Request('POST', Uri.parse('http://localhost:$_serverPort/'));