Remove deprecated APIs.

This also makes the package strong-mode clean.

R=kevmoo@google.com

Review URL: https://codereview.chromium.org//1950183003 .
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 bb1b79e..756c5bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 3.0.0
+
+* All deprecated APIs have been removed. No new APIs have been added. Packages
+  that would use 3.0.0 as a lower bound should use 2.2.0 instead—for example,
+  `http_parser: ">=2.2.0 <4.0.0"`.
+
+* Fix all strong-mode warnings.
+
 ## 2.2.1
 
 * Add support for `crypto` 1.0.0.
diff --git a/lib/http_parser.dart b/lib/http_parser.dart
index 2af4052..684c0b5 100644
--- a/lib/http_parser.dart
+++ b/lib/http_parser.dart
@@ -6,4 +6,3 @@
 export 'src/case_insensitive_map.dart';
 export 'src/http_date.dart';
 export 'src/media_type.dart';
-export 'src/web_socket.dart';
diff --git a/lib/src/authentication_challenge.dart b/lib/src/authentication_challenge.dart
index c0b63ca..66841b4 100644
--- a/lib/src/authentication_challenge.dart
+++ b/lib/src/authentication_challenge.dart
@@ -42,7 +42,7 @@
 
         // Manually parse the inner list. We need to do some lookahead to
         // disambiguate between an auth param and another challenge.
-        var params = {};
+        var params = <String, String>{};
 
         // Consume initial empty values.
         while (scanner.scan(",")) {
@@ -99,7 +99,7 @@
       scanner.scan(whitespace);
       var scheme = _scanScheme(scanner);
 
-      var params = {};
+      var params = <String, String>{};
       parseList(scanner, () => _scanAuthParam(scanner, params));
 
       scanner.expectDone();
diff --git a/lib/src/media_type.dart b/lib/src/media_type.dart
index 6a040e0..37dd6be 100644
--- a/lib/src/media_type.dart
+++ b/lib/src/media_type.dart
@@ -53,7 +53,7 @@
       var subtype = scanner.lastMatch[0];
       scanner.scan(whitespace);
 
-      var parameters = {};
+      var parameters = <String, String>{};
       while (scanner.scan(';')) {
         scanner.scan(whitespace);
         scanner.expect(token);
diff --git a/lib/src/scan.dart b/lib/src/scan.dart
index 3541038..9af8428 100644
--- a/lib/src/scan.dart
+++ b/lib/src/scan.dart
@@ -37,8 +37,8 @@
 ///
 /// Once this is finished, [scanner] will be at the next non-LWS character in
 /// the string, or the end of the string.
-List parseList(StringScanner scanner, parseElement()) {
-  var result = [];
+List/*<T>*/ parseList/*<T>*/(StringScanner scanner, /*=T*/ parseElement()) {
+  var result = /*<T>*/[];
 
   // Consume initial empty values.
   while (scanner.scan(",")) {
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 4dcee19..79ce448 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -8,7 +8,7 @@
 ///
 /// [name] should describe the type of thing being parsed, and [value] should be
 /// its actual value.
-wrapFormatException(String name, String value, body()) {
+/*=T*/ wrapFormatException/*<T>*/(String name, String value, /*=T*/ body()) {
   try {
     return body();
   } on SourceSpanFormatException catch (error) {
diff --git a/lib/src/web_socket.dart b/lib/src/web_socket.dart
deleted file mode 100644
index dee3edf..0000000
--- a/lib/src/web_socket.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2014, 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 'web_socket/channel.dart';
-export 'web_socket/compatible.dart';
-export 'web_socket/exception.dart';
diff --git a/lib/src/web_socket/channel.dart b/lib/src/web_socket/channel.dart
deleted file mode 100644
index d2a6674..0000000
--- a/lib/src/web_socket/channel.dart
+++ /dev/null
@@ -1,121 +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:convert';
-
-import 'package:async/async.dart';
-import 'package:crypto/crypto.dart';
-import 'package:stream_channel/stream_channel.dart';
-
-import '../copy/web_socket_impl.dart';
-
-/// This class is deprecated.
-///
-/// Use the [`web_socket_channel`][web_socket_channel] package instead.
-///
-/// [web_socket_channel]: https://pub.dartlang.org/packages/web_socket_channel
-@Deprecated("Will be removed in 3.0.0.")
-class WebSocketChannel extends StreamChannelMixin {
-  /// The underlying web socket.
-  ///
-  /// This is essentially a copy of `dart:io`'s WebSocket implementation, with
-  /// the IO-specific pieces factored out.
-  final WebSocketImpl _webSocket;
-
-  /// The interval for sending ping signals.
-  ///
-  /// If a ping message is not answered by a pong message from the peer, the
-  /// `WebSocket` is assumed disconnected and the connection is closed with a
-  /// [WebSocketStatus.GOING_AWAY] close code. When a ping signal is sent, the
-  /// pong message must be received within [pingInterval].
-  ///
-  /// There are never two outstanding pings at any given time, and the next ping
-  /// timer starts when the pong is received.
-  ///
-  /// By default, the [pingInterval] is `null`, indicating that ping messages
-  /// are disabled.
-  Duration get pingInterval => _webSocket.pingInterval;
-  set pingInterval(Duration value) => _webSocket.pingInterval = value;
-
-  /// The [close code][] set when the WebSocket connection is closed.
-  ///
-  /// [close code]: https://tools.ietf.org/html/rfc6455#section-7.1.5
-  ///
-  /// Before the connection has been closed, this will be `null`.
-  int get closeCode => _webSocket.closeCode;
-
-  /// The [close reason][] set when the WebSocket connection is closed.
-  ///
-  /// [close reason]: https://tools.ietf.org/html/rfc6455#section-7.1.6
-  ///
-  /// Before the connection has been closed, this will be `null`.
-  String get closeReason => _webSocket.closeReason;
-
-  Stream get stream => new StreamView(_webSocket);
-
-  /// The sink for sending values to the other endpoint.
-  ///
-  /// This has additional arguments to [WebSocketSink.close] arguments that
-  /// provide the remote endpoint reasons for closing the connection.
-  WebSocketSink get sink => new WebSocketSink._(_webSocket);
-
-  /// Signs a `Sec-WebSocket-Key` header sent by a WebSocket client as part of
-  /// the [initial handshake].
-  ///
-  /// The return value should be sent back to the client in a
-  /// `Sec-WebSocket-Accept` header.
-  ///
-  /// [initial handshake]: https://tools.ietf.org/html/rfc6455#section-4.2.2
-  static String signKey(String key) {
-    // We use [codeUnits] here rather than UTF-8-decoding the string because
-    // [key] is expected to be base64 encoded, and so will be pure ASCII.
-    return BASE64.encode(sha1.convert((key + webSocketGUID).codeUnits).bytes);
-  }
-
-  /// Creates a new WebSocket handling messaging across an existing socket.
-  ///
-  /// Because this is HTTP-API-agnostic, the initial [WebSocket handshake][]
-  /// must have already been completed on the socket before this is called.
-  ///
-  /// If [stream] is also a [StreamSink] (for example, if it's a "dart:io"
-  /// `Socket`), it will be used for both sending and receiving data. Otherwise,
-  /// it will be used for receiving data and [sink] will be used for sending it.
-  ///
-  /// [protocol] should be the protocol negotiated by this handshake, if any.
-  ///
-  /// If this is a WebSocket server, [serverSide] should be `true` (the
-  /// default); if it's a client, [serverSide] should be `false`.
-  ///
-  /// [WebSocket handshake]: https://tools.ietf.org/html/rfc6455#section-4
-  WebSocketChannel(StreamChannel<List<int>> channel,
-        {String protocol, bool serverSide: true})
-      : _webSocket = new WebSocketImpl.fromSocket(
-          channel.stream, channel.sink, protocol, serverSide);
-}
-
-/// This class is deprecated.
-///
-/// Use the [`web_socket_channel`][web_socket_channel] package instead.
-///
-/// [web_socket_channel]: https://pub.dartlang.org/packages/web_socket_channel
-@Deprecated("Will be removed in 3.0.0.")
-class WebSocketSink extends DelegatingStreamSink {
-  final WebSocketImpl _webSocket;
-
-  WebSocketSink._(WebSocketImpl webSocket)
-      : super(webSocket),
-        _webSocket = webSocket;
-
-  /// Closes the web socket connection.
-  ///
-  /// [closeCode] and [closeReason] are the [close code][] and [reason][] sent
-  /// to the remote peer, respectively. If they are omitted, the peer will see
-  /// a "no status received" code with no reason.
-  ///
-  /// [close code]: https://tools.ietf.org/html/rfc6455#section-7.1.5
-  /// [reason]: https://tools.ietf.org/html/rfc6455#section-7.1.6
-  Future close([int closeCode, String closeReason]) =>
-      _webSocket.close(closeCode, closeReason);
-}
diff --git a/lib/src/web_socket/compatible.dart b/lib/src/web_socket/compatible.dart
deleted file mode 100644
index 862f6d6..0000000
--- a/lib/src/web_socket/compatible.dart
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2014, 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:convert';
-
-import 'package:crypto/crypto.dart';
-
-import '../copy/web_socket_impl.dart';
-
-/// This class is deprecated.
-///
-/// Use the [`web_socket_channel`][web_socket_channel] package instead.
-///
-/// [web_socket_channel]: https://pub.dartlang.org/packages/web_socket_channel
-@Deprecated("Will be removed in 3.0.0.")
-abstract class CompatibleWebSocket implements Stream, StreamSink {
-  /// The interval for sending ping signals.
-  ///
-  /// If a ping message is not answered by a pong message from the peer, the
-  /// `WebSocket` is assumed disconnected and the connection is closed with a
-  /// [WebSocketStatus.GOING_AWAY] close code. When a ping signal is sent, the
-  /// pong message must be received within [pingInterval].
-  ///
-  /// There are never two outstanding pings at any given time, and the next ping
-  /// timer starts when the pong is received.
-  ///
-  /// By default, the [pingInterval] is `null`, indicating that ping messages
-  /// are disabled.
-  Duration pingInterval;
-
-  /// The [close code][] set when the WebSocket connection is closed.
-  ///
-  /// [close code]: https://tools.ietf.org/html/rfc6455#section-7.1.5
-  ///
-  /// Before the connection has been closed, this will be `null`.
-  int get closeCode;
-
-  /// The [close reason][] set when the WebSocket connection is closed.
-  ///
-  /// [close reason]: https://tools.ietf.org/html/rfc6455#section-7.1.6
-  ///
-  /// Before the connection has been closed, this will be `null`.
-  String get closeReason;
-
-  /// Signs a `Sec-WebSocket-Key` header sent by a WebSocket client as part of
-  /// the [initial handshake].
-  ///
-  /// The return value should be sent back to the client in a
-  /// `Sec-WebSocket-Accept` header.
-  ///
-  /// [initial handshake]: https://tools.ietf.org/html/rfc6455#section-4.2.2
-  static String signKey(String key) {
-    // We use [codeUnits] here rather than UTF-8-decoding the string because
-    // [key] is expected to be base64 encoded, and so will be pure ASCII.
-    return BASE64.encode(sha1.convert((key + webSocketGUID).codeUnits).bytes);
-  }
-
-  /// Creates a new WebSocket handling messaging across an existing socket.
-  ///
-  /// Because this is HTTP-API-agnostic, the initial [WebSocket handshake][]
-  /// must have already been completed on the socket before this is called.
-  ///
-  /// If [stream] is also a [StreamSink] (for example, if it's a "dart:io"
-  /// `Socket`), it will be used for both sending and receiving data. Otherwise,
-  /// it will be used for receiving data and [sink] will be used for sending it.
-  ///
-  /// [protocol] should be the protocol negotiated by this handshake, if any.
-  ///
-  /// If this is a WebSocket server, [serverSide] should be `true` (the
-  /// default); if it's a client, [serverSide] should be `false`.
-  ///
-  /// [WebSocket handshake]: https://tools.ietf.org/html/rfc6455#section-4
-  factory CompatibleWebSocket(Stream<List<int>> stream,
-        {StreamSink<List<int>> sink, String protocol, bool serverSide: true}) {
-    if (sink == null) {
-      if (stream is! StreamSink) {
-        throw new ArgumentError("If stream isn't also a StreamSink, sink must "
-            "be passed explicitly.");
-      }
-      sink = stream as StreamSink;
-    }
-
-    return new WebSocketImpl.fromSocket(stream, sink, protocol, serverSide);
-  }
-
-  /// Closes the web socket connection.
-  ///
-  /// [closeCode] and [closeReason] are the [close code][] and [reason][] sent
-  /// to the remote peer, respectively. If they are omitted, the peer will see
-  /// a "no status received" code with no reason.
-  ///
-  /// [close code]: https://tools.ietf.org/html/rfc6455#section-7.1.5
-  /// [reason]: https://tools.ietf.org/html/rfc6455#section-7.1.6
-  Future close([int closeCode, String closeReason]);
-}
diff --git a/lib/src/web_socket/exception.dart b/lib/src/web_socket/exception.dart
deleted file mode 100644
index c1a6473..0000000
--- a/lib/src/web_socket/exception.dart
+++ /dev/null
@@ -1,19 +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.
-
-/// This class is deprecated.
-///
-/// Use the [`web_socket_channel`][web_socket_channel] package instead.
-///
-/// [web_socket_channel]: https://pub.dartlang.org/packages/web_socket_channel
-@Deprecated("Will be removed in 3.0.0.")
-class CompatibleWebSocketException implements Exception {
-  final String message;
-
-  CompatibleWebSocketException([this.message]);
-
-  String toString() => message == null
-      ? "CompatibleWebSocketException" :
-        "CompatibleWebSocketException: $message";
-}
diff --git a/pubspec.yaml b/pubspec.yaml
index 804d951..21a3977 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: http_parser
-version: 2.2.1
+version: 3.0.0
 author: "Dart Team <misc@dartlang.org>"
 homepage: https://github.com/dart-lang/http_parser
 description: >
diff --git a/test/web_socket_test.dart b/test/web_socket_test.dart
deleted file mode 100644
index 53aa5be..0000000
--- a/test/web_socket_test.dart
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright (c) 2014, 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.
-
-@TestOn('vm')
-
-import 'dart:io';
-
-import 'package:http_parser/http_parser.dart';
-import 'package:stream_channel/stream_channel.dart';
-import 'package:test/test.dart';
-
-void main() {
-  group("using WebSocketChannel", () {
-    test("a client can communicate with a WebSocket server", () async {
-      var server = await HttpServer.bind("localhost", 0);
-      server.transform(new WebSocketTransformer()).listen((webSocket) {
-        webSocket.add("hello!");
-        webSocket.listen((request) {
-          expect(request, equals("ping"));
-          webSocket.add("pong");
-          webSocket.close();
-        });
-      });
-
-      var client = new HttpClient();
-      var request = await client.openUrl(
-          "GET", Uri.parse("http://localhost:${server.port}"));
-      request.headers
-        ..set("Connection", "Upgrade")
-        ..set("Upgrade", "websocket")
-        ..set("Sec-WebSocket-Key", "x3JJHMbDL1EzLkh9GBhXDw==")
-        ..set("Sec-WebSocket-Version", "13");
-
-      var response = await request.close();
-      var socket = await response.detachSocket();
-      var innerChannel = new StreamChannel(socket, socket);
-      var webSocket = new WebSocketChannel(innerChannel, serverSide: false);
-
-      var n = 0;
-      await webSocket.stream.listen((message) {
-        if (n == 0) {
-          expect(message, equals("hello!"));
-          webSocket.sink.add("ping");
-        } else if (n == 1) {
-          expect(message, equals("pong"));
-          webSocket.sink.close();
-          server.close();
-        } else {
-          fail("Only expected two messages.");
-        }
-        n++;
-      }).asFuture();
-    });
-
-    test("a server can communicate with a WebSocket client", () async {
-      var server = await HttpServer.bind("localhost", 0);
-      server.listen((request) async {
-        var response = request.response;
-        response.statusCode = 101;
-        response.headers
-          ..set("Connection", "Upgrade")
-          ..set("Upgrade", "websocket")
-          ..set("Sec-WebSocket-Accept", CompatibleWebSocket
-              .signKey(request.headers.value('Sec-WebSocket-Key')));
-        response.contentLength = 0;
-
-        var socket = await response.detachSocket();
-        var innerChannel = new StreamChannel(socket, socket);
-        var webSocket = new WebSocketChannel(innerChannel);
-        webSocket.sink.add("hello!");
-
-        var message = await webSocket.stream.first;
-        expect(message, equals("ping"));
-        webSocket.sink.add("pong");
-        webSocket.sink.close();
-      });
-
-      var webSocket = await WebSocket.connect('ws://localhost:${server.port}');
-      var n = 0;
-      await webSocket.listen((message) {
-        if (n == 0) {
-          expect(message, equals("hello!"));
-          webSocket.add("ping");
-        } else if (n == 1) {
-          expect(message, equals("pong"));
-          webSocket.close();
-          server.close();
-        } else {
-          fail("Only expected two messages.");
-        }
-        n++;
-      }).asFuture();
-    });
-  });
-
-  group("using CompatibleWebSocket", () {
-    test("a client can communicate with a WebSocket server", () {
-      return HttpServer.bind("localhost", 0).then((server) {
-        server.transform(new WebSocketTransformer()).listen((webSocket) {
-          webSocket.add("hello!");
-          webSocket.listen((request) {
-            expect(request, equals("ping"));
-            webSocket.add("pong");
-            webSocket.close();
-          });
-        });
-
-        var client = new HttpClient();
-        return client
-            .openUrl("GET", Uri.parse("http://localhost:${server.port}"))
-            .then((request) {
-          request.headers
-            ..set("Connection", "Upgrade")
-            ..set("Upgrade", "websocket")
-            ..set("Sec-WebSocket-Key", "x3JJHMbDL1EzLkh9GBhXDw==")
-            ..set("Sec-WebSocket-Version", "13");
-          return request.close();
-        }).then((response) => response.detachSocket()).then((socket) {
-          var webSocket = new CompatibleWebSocket(socket, serverSide: false);
-
-          var n = 0;
-          return webSocket.listen((message) {
-            if (n == 0) {
-              expect(message, equals("hello!"));
-              webSocket.add("ping");
-            } else if (n == 1) {
-              expect(message, equals("pong"));
-              webSocket.close();
-              server.close();
-            } else {
-              fail("Only expected two messages.");
-            }
-            n++;
-          }).asFuture();
-        });
-      });
-    });
-
-    test("a server can communicate with a WebSocket client", () {
-      return HttpServer.bind("localhost", 0).then((server) {
-        server.listen((request) {
-          var response = request.response;
-          response.statusCode = 101;
-          response.headers
-            ..set("Connection", "Upgrade")
-            ..set("Upgrade", "websocket")
-            ..set("Sec-WebSocket-Accept", CompatibleWebSocket
-                .signKey(request.headers.value('Sec-WebSocket-Key')));
-          response.contentLength = 0;
-          response.detachSocket().then((socket) {
-            var webSocket = new CompatibleWebSocket(socket);
-            webSocket.add("hello!");
-            webSocket.first.then((request) {
-              expect(request, equals("ping"));
-              webSocket.add("pong");
-              webSocket.close();
-            });
-          });
-        });
-
-        return WebSocket
-            .connect('ws://localhost:${server.port}')
-            .then((webSocket) {
-          var n = 0;
-          return webSocket.listen((message) {
-            if (n == 0) {
-              expect(message, equals("hello!"));
-              webSocket.add("ping");
-            } else if (n == 1) {
-              expect(message, equals("pong"));
-              webSocket.close();
-              server.close();
-            } else {
-              fail("Only expected two messages.");
-            }
-            n++;
-          }).asFuture();
-        });
-      });
-    });
-  });
-}