Fix most strong mode warnings.

There are two remaining warnings. One will go away when a strong mode
version of the analyzer has been released; the other will go away when
dart-lang/sdk#26143 is fixed.

R=jmesserly@google.com

Review URL: https://codereview.chromium.org//1843323002 .
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 1db0a15..198b1b6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.0.1
+
+* Fix most strong mode errors and warnings.
+
 ## 2.0.0
 
 * **Breaking:** Change the signature of `HttpMultiServer.loopbackSecure()` to
diff --git a/lib/http_multi_server.dart b/lib/http_multi_server.dart
index 6c4e468..18d42cf 100644
--- a/lib/http_multi_server.dart
+++ b/lib/http_multi_server.dart
@@ -5,6 +5,8 @@
 import 'dart:async';
 import 'dart:io';
 
+import 'package:async/async.dart';
+
 import 'src/multi_headers.dart';
 import 'src/utils.dart';
 
@@ -86,7 +88,7 @@
       : _servers = servers.toSet(),
         defaultResponseHeaders = new MultiHeaders(
             servers.map((server) => server.defaultResponseHeaders)),
-        super(mergeStreams(servers));
+        super(StreamGroup.merge(servers));
 
   /// Creates an [HttpServer] listening on all available loopback addresses for
   /// this computer.
@@ -121,36 +123,28 @@
   /// [HttpServer.bindSecure].
   static Future<HttpServer> _loopback(int port,
       Future<HttpServer> bind(InternetAddress address, int port),
-      [int remainingRetries]) {
+      [int remainingRetries]) async {
     if (remainingRetries == null) remainingRetries = 5;
 
-    return Future.wait([
-      supportsIpV6,
-      bind(InternetAddress.LOOPBACK_IP_V4, port)
-    ]).then((results) {
-      var supportsIpV6 = results[0];
-      var v4Server = results[1];
+    var v4Server = await bind(InternetAddress.LOOPBACK_IP_V4, port);
+    if (!await supportsIpV6) return v4Server;
 
-      if (!supportsIpV6) return v4Server;
-
+    try {
       // Reuse the IPv4 server's port so that if [port] is 0, both servers use
       // the same ephemeral port.
-      return bind(InternetAddress.LOOPBACK_IP_V6, v4Server.port)
-          .then((v6Server) {
-        return new HttpMultiServer([v4Server, v6Server]);
-      }).catchError((error) {
-        if (error is! SocketException) throw error;
-        if (error.osError.errorCode != _addressInUseErrno) throw error;
-        if (port != 0) throw error;
-        if (remainingRetries == 0) throw error;
+      var v6Server = await bind(InternetAddress.LOOPBACK_IP_V6, v4Server.port);
+      return new HttpMultiServer([v4Server, v6Server]);
+    } on SocketException catch (error) {
+      if (error.osError.errorCode != _addressInUseErrno) rethrow;
+      if (port != 0) rethrow;
+      if (remainingRetries == 0) rethrow;
 
-        // A port being available on IPv4 doesn't necessarily mean that the same
-        // port is available on IPv6. If it's not (which is rare in practice),
-        // we try again until we find one that's available on both.
-        v4Server.close();
-        return _loopback(port, bind, remainingRetries - 1);
-      });
-    });
+      // A port being available on IPv4 doesn't necessarily mean that the same
+      // port is available on IPv6. If it's not (which is rare in practice),
+      // we try again until we find one that's available on both.
+      v4Server.close();
+      return await _loopback(port, bind, remainingRetries - 1);
+    }
   }
 
   Future close({bool force: false}) =>
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index ceb5c82..19188cb 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -5,56 +5,20 @@
 import 'dart:async';
 import 'dart:io';
 
-/// Merges all streams in [streams] into a single stream that emits all of their
-/// values.
-///
-/// The returned stream will be closed only when every stream in [streams] is
-/// closed.
-Stream mergeStreams(Iterable<Stream> streams) {
-  var subscriptions = new Set();
-  var controller;
-  controller = new StreamController(onListen: () {
-    for (var stream in streams) {
-      var subscription;
-      subscription = stream.listen(controller.add,
-          onError: controller.addError,
-          onDone: () {
-        subscriptions.remove(subscription);
-        if (subscriptions.isEmpty) controller.close();
-      });
-      subscriptions.add(subscription);
-    }
-  }, onCancel: () {
-    for (var subscription in subscriptions) {
-      subscription.cancel();
-    }
-  }, onPause: () {
-    for (var subscription in subscriptions) {
-      subscription.pause();
-    }
-  }, onResume: () {
-    for (var subscription in subscriptions) {
-      subscription.resume();
-    }
-  }, sync: true);
-
-  return controller.stream;
-}
-
 /// A cache for [supportsIpV6].
 bool _supportsIpV6;
 
 /// Returns whether this computer supports binding to IPv6 addresses.
-Future<bool> get supportsIpV6 {
-  if (_supportsIpV6 != null) return new Future.value(_supportsIpV6);
+Future<bool> get supportsIpV6 async {
+  if (_supportsIpV6 != null) return _supportsIpV6;
 
-  return ServerSocket.bind(InternetAddress.LOOPBACK_IP_V6, 0).then((socket) {
+  try {
+    var socket = await ServerSocket.bind(InternetAddress.LOOPBACK_IP_V6, 0);
     _supportsIpV6 = true;
     socket.close();
     return true;
-  }).catchError((error) {
-    if (error is! SocketException) throw error;
+  } on SocketException catch (_) {
     _supportsIpV6 = false;
     return false;
-  });
+  }
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index 44daa8f..647b7eb 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,10 +1,11 @@
 name: http_multi_server
-version: 2.0.0
+version: 2.0.1
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://github.com/dart-lang/http_multi_server
 description:
   A dart:io HttpServer wrapper that handles requests from multiple servers.
 dev_dependencies:
+  async: "^1.2.0"
   test: ">=0.12.0 <0.13.0"
   http: ">=0.11.0 <0.12.0"
 environment: