Deprecate Delegating*.typed utilities (#99)

Most of these have simpler or safer versions in Dart 2. The "Sink"
classes have a workaround which is ugly, but these also had nearly no
usage.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index da244b5..1de2581 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,16 @@
 ## 2.4.1-dev
 
+* Deprecate `DelegatingStream.typed`. Use `Stream.cast` instead.
+* Deprecate `DelegatingStreamSubcription.typed` and
+  `DelegatingStreamConsumer.typed`. For each of these the `Stream` should be
+  cast to the correct type before being used.
+* Deprecate `DelegatingStreamSink.typed`. `DelegatingSink.typed`,
+  `DelegatingEventSink.typed`, `DelegatingStreamConsumer.typed`. For each of
+  these a new `StreamController` can be constructed to forward to the sink.
+  `StreamController<T>()..stream.cast<S>().pipe(sink)`
+* Deprecate `typedStreamTransformer`. Cast after transforming instead.
+* Deprecate `StreamSinkTransformer.typed` since there was no usage.
+
 ## 2.4.0
 
 * Add `StreamGroup.mergeBroadcast()` utility.
diff --git a/README.md b/README.md
index 6e2b8de..359b93a 100644
--- a/README.md
+++ b/README.md
@@ -22,11 +22,6 @@
   [`DelegatingEventSink`][DelegatingEventSink], and
   [`DelegatingStreamSink`][DelegatingStreamSink].
 
-  The delegating classes all have `.typed()` constructors which allow users to
-  cast the generic type parameters in a way that's safe for strong mode. For
-  example, if `future` is a `Future<dynamic>` and you know it actually contains an
-  `int`, you can write `DelegatingFuture.typed<int>(future)`.
-
 * The [`FutureGroup`][FutureGroup] class makes it easy to wait until a group of
   features that may change over time completes.
 
diff --git a/lib/src/delegate/event_sink.dart b/lib/src/delegate/event_sink.dart
index 977ee64..bc33b19 100644
--- a/lib/src/delegate/event_sink.dart
+++ b/lib/src/delegate/event_sink.dart
@@ -22,6 +22,8 @@
   /// instance of `EventSink`, not `EventSink<T>`. This means that calls to
   /// [add] may throw a [CastError] if the argument type doesn't match the
   /// reified type of [sink].
+  @Deprecated(
+      'Use StreamController<T>(sync: true)..stream.cast<S>().pipe(sink)')
   static EventSink<T> typed<T>(EventSink sink) =>
       sink is EventSink<T> ? sink : DelegatingEventSink._(sink);
 
diff --git a/lib/src/delegate/sink.dart b/lib/src/delegate/sink.dart
index c1e01d7..57ef2a0 100644
--- a/lib/src/delegate/sink.dart
+++ b/lib/src/delegate/sink.dart
@@ -20,6 +20,8 @@
   /// instance of `Sink`, not `Sink<T>`. This means that calls to [add] may
   /// throw a [CastError] if the argument type doesn't match the reified type of
   /// [sink].
+  @Deprecated(
+      'Use StreamController<T>(sync: true)..stream.cast<S>().pipe(sink)')
   static Sink<T> typed<T>(Sink sink) =>
       sink is Sink<T> ? sink : DelegatingSink._(sink);
 
diff --git a/lib/src/delegate/stream.dart b/lib/src/delegate/stream.dart
index 116d11f..1585eab 100644
--- a/lib/src/delegate/stream.dart
+++ b/lib/src/delegate/stream.dart
@@ -21,5 +21,6 @@
   /// original generic type, by asserting that its events are instances of `T`
   /// whenever they're provided. If they're not, the stream throws a
   /// [CastError].
+  @Deprecated('Use stream.cast instead')
   static Stream<T> typed<T>(Stream stream) => stream.cast();
 }
diff --git a/lib/src/delegate/stream_consumer.dart b/lib/src/delegate/stream_consumer.dart
index 591f903..6b92006 100644
--- a/lib/src/delegate/stream_consumer.dart
+++ b/lib/src/delegate/stream_consumer.dart
@@ -22,6 +22,8 @@
   /// instance of `StreamConsumer`, not `StreamConsumer<T>`. This means that
   /// calls to [addStream] may throw a [CastError] if the argument type doesn't
   /// match the reified type of [consumer].
+  @Deprecated(
+      'Use StreamController<T>(sync: true)..stream.cast<S>().pipe(sink)')
   static StreamConsumer<T> typed<T>(StreamConsumer consumer) =>
       consumer is StreamConsumer<T>
           ? consumer
diff --git a/lib/src/delegate/stream_sink.dart b/lib/src/delegate/stream_sink.dart
index 3971189..9005d1d 100644
--- a/lib/src/delegate/stream_sink.dart
+++ b/lib/src/delegate/stream_sink.dart
@@ -25,6 +25,8 @@
   /// of `StreamSink`, not `StreamSink<T>`. This means that calls to [add] may
   /// throw a [CastError] if the argument type doesn't match the reified type of
   /// [sink].
+  @Deprecated(
+      'Use StreamController<T>(sync: true)..stream.cast<S>().pipe(sink)')
   static StreamSink<T> typed<T>(StreamSink sink) =>
       sink is StreamSink<T> ? sink : DelegatingStreamSink._(sink);
 
diff --git a/lib/src/delegate/stream_subscription.dart b/lib/src/delegate/stream_subscription.dart
index 7d258a8..392e27b 100644
--- a/lib/src/delegate/stream_subscription.dart
+++ b/lib/src/delegate/stream_subscription.dart
@@ -23,6 +23,8 @@
   /// regardless of its original generic type, by asserting that its events are
   /// instances of `T` whenever they're provided. If they're not, the
   /// subscription throws a [CastError].
+  @Deprecated('Use Stream.cast instead')
+  // TODO - Remove `TypeSafeStreamSubscription` and tests when removing this.
   static StreamSubscription<T> typed<T>(StreamSubscription subscription) =>
       subscription is StreamSubscription<T>
           ? subscription
diff --git a/lib/src/lazy_stream.dart b/lib/src/lazy_stream.dart
index d2ac33c..f5e65d1 100644
--- a/lib/src/lazy_stream.dart
+++ b/lib/src/lazy_stream.dart
@@ -4,7 +4,6 @@
 
 import 'dart:async';
 
-import 'delegate/stream.dart';
 import 'stream_completer.dart';
 import 'utils.dart';
 
@@ -40,11 +39,9 @@
 
     Stream<T> stream;
     if (result is Future<Stream<T>>) {
-      stream = StreamCompleter.fromFuture(result.then((stream) {
-        return DelegatingStream.typed<T>(stream);
-      }));
+      stream = StreamCompleter.fromFuture(result);
     } else {
-      stream = DelegatingStream.typed<T>(result as Stream);
+      stream = result as Stream<T>;
     }
 
     return stream.listen(onData,
diff --git a/lib/src/stream_sink_transformer.dart b/lib/src/stream_sink_transformer.dart
index c50cf17..1dc27ed 100644
--- a/lib/src/stream_sink_transformer.dart
+++ b/lib/src/stream_sink_transformer.dart
@@ -53,6 +53,8 @@
   /// This means that calls to [StreamSink.add] on the returned sink may throw a
   /// [CastError] if the argument type doesn't match the reified type of the
   /// sink.
+  @deprecated
+  // TODO remove TypeSafeStreamSinkTransformer
   static StreamSinkTransformer<S, T> typed<S, T>(
           StreamSinkTransformer transformer) =>
       transformer is StreamSinkTransformer<S, T>
diff --git a/lib/src/stream_sink_transformer/typed.dart b/lib/src/stream_sink_transformer/typed.dart
index c27bd24..4743c94 100644
--- a/lib/src/stream_sink_transformer/typed.dart
+++ b/lib/src/stream_sink_transformer/typed.dart
@@ -4,7 +4,6 @@
 
 import 'dart:async';
 
-import '../delegate/stream_sink.dart';
 import '../stream_sink_transformer.dart';
 
 /// A wrapper that coerces the generic type of the sink returned by an inner
@@ -16,6 +15,6 @@
   TypeSafeStreamSinkTransformer(this._inner);
 
   @override
-  StreamSink<S> bind(StreamSink<T> sink) =>
-      DelegatingStreamSink.typed(_inner.bind(sink));
+  StreamSink<S> bind(StreamSink<T> sink) => StreamController(sync: true)
+    ..stream.cast<dynamic>().pipe(_inner.bind(sink));
 }
diff --git a/lib/src/typed_stream_transformer.dart b/lib/src/typed_stream_transformer.dart
index 2366505..c1af93f 100644
--- a/lib/src/typed_stream_transformer.dart
+++ b/lib/src/typed_stream_transformer.dart
@@ -4,14 +4,13 @@
 
 import 'dart:async';
 
-import 'delegate/stream.dart';
-
 /// Creates a wrapper that coerces the type of [transformer].
 ///
 /// This soundly converts a [StreamTransformer] to a `StreamTransformer<S, T>`,
 /// regardless of its original generic type, by asserting that the events
 /// emitted by the transformed stream are instances of `T` whenever they're
 /// provided. If they're not, the stream throws a [CastError].
+@Deprecated('Use Stream.cast after binding a transformer instead')
 StreamTransformer<S, T> typedStreamTransformer<S, T>(
         StreamTransformer transformer) =>
     transformer is StreamTransformer<S, T>
@@ -26,6 +25,5 @@
   _TypeSafeStreamTransformer(this._inner);
 
   @override
-  Stream<T> bind(Stream<S> stream) =>
-      DelegatingStream.typed(_inner.bind(stream));
+  Stream<T> bind(Stream<S> stream) => _inner.bind(stream).cast();
 }