# Dart 2.0 - Core Library Changes
2017-10-27
@floitschG

This document provides an overview of the planned library changes for Dart 2.0.
The proposed changes are not yet final. There are still changes that will happen.

Please provide feedback.

This document covers planned changes to the following libraries: `async`, `collection`, `convert`, `core`, `isolate`, `math`, and `typed_data`. The `mirrors` library needs some updates, but we haven't yet found the time to improve it.

The `io` library, as well as all browser related libraries (`html`, `indexed_db`, `js`, `svg`, `web_audio`, `web_gl` and `web_sql`) are, for organizational reasons, maintained by different teams. We work with them to maintain consistency, but these libraries are not covered in this document.

All changes have been collected in the following CL: https://dart-review.googlesource.com/15127.

The patch contains all proposed changes, but is not complete, nor error-free (and might be out-of-date in some minor details). It is intended to be a tool to help read this document by showing old and new signatures next to each other.

## Updates
* 2017-10-30: added `bufferSize` argument to `Stream.replay`.

## Preface
Library design is opinion based, and it's impossible to get 100% agreement on what a perfect library should look like. For example, `Iterable.isNotEmpty` is a thorn in some developer's eyes; yet considered to be a great addition for others.

Similarly, we got mixed feedback on many occasions. For the same interface, we received requests (usually, but not always, from different developers) to add more methods, and to stop "bloating" the APIs.

In the end, we take every feedback we can get and evaluate it. In some cases, we do adapt the libraries, but very often, sadly, we reject change requests. This shouldn't taken as a sign that we don't listen to feedback. Not every feature can make it into the libraries; not every change fits the Dart library's style.

## Motivation
Our main goal is to provide libraries that are easy to use correctly. After that, we strive for consistency, completeness and convenience while staying minimal. All of these properties are subjective and depend heavily on (amongst other things) the use cases, the size of projects, the education of the developers, and taste. 

We believe that the Dart 1.x libraries were well received, and want to keep the style of the libraries similar to what developers are used to. Despite a relatively large number of accepted issues, we believe that the proposed changes will not fundamentally change the core libraries, and just make them "better".

### Holistic Approach
This document is big. While we could have split it for easier reading, it is not how we, the library team, work on the libraries. It is our opinion that library design should be done holistically (ideally together with the language design). One of the major qualities of a good library is a consistent feel. This is, why changes usually happen in bigger chunks: if one element is changed, some other might also need changes.

There are lots of cross-dependencies that make a holistic approach more successful: if we add a method to `Iterable`, we also have to consider it for `Stream`. If we decide that helper classes should go into packages, then we should do that for all libraries and not just some. (Otherwise we end up with a mixed impression: "why is this here, but not the other?").

Just to give a few more examples:
* Moving `min` and `max` to` int`, `double` and `num` has repercussions on the `BigInt` class. With that move `BigInt.min` is the natural place for `BigInt`'s `min`. If they didn't move, then we would need to rethink how to write our `BigInt` class, and where to put `BigInt`'s `min`. It could be that a member function (like `.clampMin`) would then be a better approach.
* The `Uri` class should use the same modifying method name, `with`, as `DateTime`. This means that we want to look at the two classes at the same time.

These might sound like minor issues, but as library designers we care deeply about how a library feels as a whole.

### Correct Use
For each item of functionality, we try to understand how our users will use it. Frequently, this involves showing code samples to coworkers, and friends, and ask them what they expect the code would do.

If necessary, we adapt the functionality, remove it entirely, or find better names. In this sense  correct interpretation and correct usage are given a higher priority than consistency, completeness or convenience.

### Consistency
Just after "correct use" we put consistency. By providing a consistent API, developers have to learn fewer concepts, and are more productive because they need to search for documentation less often. Consistency is always a requirement to give a language its own style. We often use the term "darty" to refer to APIs that feel similar to Dart's core libraries. This can only be achieved through a consistent use within the core libraries themselves.

Consistency comes in multiple flavors:
- Naming: Methods that do similar things, should have similar names. When possible, conventions make it easier to guess the name and behavior of members. For example, asX always wraps, and toX creates a copy.
- Signatures: Methods with similar arguments should have similar signatures, and parameters that could be given in different ways should agree. For example, Dart always expects ranges as "from", "to" (exclusive). No core Dart function will take "from" and "length".

### Completeness
Completeness comes in two parts:
1. Completeness for consistency sake: if we have `firstWhere`, then we should have `lastWhere` as well.
2. Completeness in terms of functionality. Our libraries should provide the functionality to do common tasks without requiring additional packages. Some of our libraries didn't have functionality that is commonly useful. For example, `DateTime` was missing functionality to work with dates.

### Performance
In general we won't mention performance a lot. That's not because we don't care for it, though. Every feature we add to the libraries is supposed to be efficient. In fact, it is important to note that some features are not in the library plan, specifically, because they can't be implemented efficiently, or would make the compilation of Dart harder.

Also, unless we completely redesign the libraries, there are only very few things that can affect the performance. Almost all the improvements are by refactoring the internals of the libraries, or by improving optimizations. In fact, the biggest changes we dared doing (rewriting the `StreamController`), was with the idea of making it simpler and thus more efficient. We don't expect to see big performance gains, but performance was on our mind. Similarly, the refactorings to `Uri` were driven by known inefficiencies when compiling to JavaScript.

We were always receptive to non-API changes that could improve the performance of the libraries. For example, we moved some concurrent-modification checks into `assert`s, because they showed up on production profiles. In practice these checks are most helpful during development and can be removed during production.

### New Language Features
Some of the proposed changes would look different if the Dart language had different features. For example, extension methods would incite us to move some methods out of classes. The print function should use "rest"-arguments instead of 8 optional positional arguments.

We agree with this sentiment, but we don't want to make our users wait for language features. This is a typical case of perfect being the enemy of good.
Obviously, we don't completely ignore upcoming features, either. When we know which features will come (like rest arguments), we prepare the libraries for them. Switching the print method from 8 arguments to rest-arguments is a non-breaking change.

### In this Document
Throughout this document, we will regularly refer to the above-mentioned properties ("correct use", "consistency" and "completeness"). When appropriate we will, however, group related changes into their own sections. It is easier to think of one big change to, for example, `DateTime` than to see its changes in different categories.

We will also often justify changes as "cleanups". These are often a combination of multiple reasons: correct use, consistency, minimal design, or simply "because it should be this way". Cleanups are often done in classes that already required other changes (and where additional breakages are absorbed by the initial change), or because they are very simple to fix.

#### Breaking Changes
Most of the changes in this document are breaking in some way or another. Even adding a method to an existing class breaks every user that implements the same interface. For some classes implementing the same interface is impossible (`int`, `String`, ...), or very unlikely (for example, `DateTime`), but some classes are subtyped often and changing them can break a significant number of users (for instance `Iterable`). This kind of breakage is, however, simple to fix: in many cases using provided mixins or baseclasses (such as `ListMixin` and `ListBase`) completely avoid breakages, and in others (like `TypeSafeList` from `package:collection`) it's as easy as adding new forwarding methods.

Throughout this document we will provide comments in quotation sections, providing opinions on how breaking these changes are. For example:

> This change is unlikely to break any user. However, even if the class is subtyped, implementing the missing method is trivial.

We won't provide comments for missing methods. As discussed above, developers that implement interfaces from the core libraries simply need to add the missing members. When the classes are commonly subclassed we will provide enough information to make this a painless process.

We won't provide comments when we move classes into packages or other libraries. For all of them, the following opinion applies:

> Moving the class to a package or other library is breaking, but can be detected statically. The fix is to simply add the corresponding package to the pubspec (if it isn't there yet) and to import that library that contains the class.

#### Constants
The convention to name constants with lowercase identifiers was only introduced after the Dart 1.x libraries were finished. With Dart 2.0 we now refactor all of our constants to follow the Dart style guide. Some of these renamings are mentioned in the remainder of this document, but most aren't.

> Renaming constants to lower-case may introduce two cases of breakages:
>  1. Users of the constants have to update their code.
>  2. Unqualified accesses to super members could now resolve to a global constant.
>
> We can ease the migration to lower-case constants by providing both at the same time for some time. The migration itself is extremely straight-forward and can be automated in many cases.
>
> The second reason for breakages is extremely rare. It's also likely that the type system would catch many of them. We don't think we have to worry about that case.

## dart:core
#### Annotations
We renamed the `expires` field of the `Deprecated` class to `message`.

We removed the `Proxy` (and `proxy`) annotation, since it is not useful in Dart 2.0 anymore.

> Renaming instance members is, in theory, slightly more breaking than static elements. If a user accessed the expires field of Deprecated through dynamic, a static analysis tool would not be able to detect the breakage. This, on its own, is already very unlikely. Furthermore, this class and field is not used very frequently.

#### Random
The `Random` class was moved from `dart:math` to `dart:core`. The `int`, `double` and `bool` classes now have a static `random()` method that returns a random value of the corresponding type. The int type has two versions of the random method: `int random(int max)` and `int randomRange(int from, int to)`. (We are not yet fully sold on `randomRange`. It sounds like it would return a random range and not a value in that range).

Moving Random to dart:core has two advantages:
1. Random is commonly used, and
2. it makes the dart:math library really math centric. As described in the dart:math section, the `math` library has been cleaned and now serves the intended purpose of providing mathematical functionality.

#### Numbers
The `clamp` method on numbers is used to bring a specific value into a certain range. Unfortunately, there is no good way to type it on `num` while still returning the receiver type on the two subtypes `int` and `double`. That is, we would like `double.clamp` to take two doubles and return again a double. For this reason, we decided to move clamp to the respective subtypes and remove it from `num`.

Similar reasons (in addition to those mentioned in earlier) were considered when we decided to move `min` and `max` from `dart:math` as static methods to `num`, `int` and `double`. This makes the functions type-safer and makes the generic argument unnecessary. It also makes the `int` and `double` versions faster.

The `int.toRadixString` function now takes a `digits` and `prefix` named argument:
``` dart
  /**
   * ...
   * If [digits] is present, returns at least [digits] digits, filling the
   * missing digits with `0`.
   *
   * If [prefix] is provided, prefixes the result with the given [prefix].
   *
   * Example:
   * ```
   * print(26.toRadixString(16, digits: 4, prefix: "0x"));  // => "0x001A"
   * ```
   */
  String toRadixString(int radix, {int digits, String prefix = ""});
```
(`digits` doesn't indicate that this is the *minimal* number of digits, so we might revisit this argument name).

Outside the browser integers are now fixed-size (64 bits) in Dart 2.0. The `int` class thus gains a `>>>` (unsigned shift) operator. Similar to most other C-like languages, the `>>` operator is now the signed shift, smearing the sign-bit, and `>>>` is the unsigned shift, filling in `0`s at the left.

This change is pending language changes, since this operator doesn't exist in Dart yet. Since `int` is not user-implementable, this change is non-breaking and could be shipped at a later Dart 2.x time.

Also see the dart:typed_data section for the introduction of a `BigInt` class.

> Moving the `clamp` method to `int` and `double` is potentially breaking. Users who need to do the clamping on `num` need to reimplement the function themselves. The benefit of having a type-safe variant on `int` and `double` should outweigh the breakage-cost.
>
> All other number API changes are non-breaking.

#### Print
We are modifying `print` to take multiple arguments. For now we just take up to 8 optional arguments. Eventually, the function will use rest arguments to take an arbitrary number of objects.

This change is motivated by the desire to `print` objects on consoles and still be able to inspect them, similar to what happens when using `console.log` in JavaScript.

As a consequence we have to change the `Zone` API as well: the `print` hook in `Zone`s now takes a `List<Object>` instead of a simple `String`.

Also note that we now accept `print` with no arguments as well.

> The `print` change itself is non-breaking.
>
> The API change to `Zone` is breaking, but only affects developers that hook into the `print` callback of `Zone`s. The fix for these hooks is easy.

#### Uri
The `Uri` class will change behavior. The current class is subtly incompatible with the URL functionality built into browsers, which makes it impractical to use the native methods even when they are available. That's unnecessarily inefficient.

We will change the class to behave very closely like the WHATWG URL specification, but will still maintain mostly the same API, with few major changes. Contrary to the WHATWG_URL specification, we will still be able to represent relative URI references, which the DOM URL doesn't allow, and to handle `package:` URIs in a predictable way.

One major change is that interpretation of the URI query is delegated to a new class, a `UriQuery`, instead of having multiple methods on the `Uri` class itself (and requests for more).
An interpreted query will no longer be treated as just a map from string to string, which was always inadequate (one query key can have multiple values). This affects all places in the API where a query is represented as a `Map`, including constructor arguments. Instead of:
``` dart
var uri = Uri.http("example.org", "/path", {"q": "dart"});  // Using optional `new`.
```
you will have to write:
```
var uri = Uri.http("example.org", "/path", UriQuery({"q": "dart"}));  // Using optional `new`.
```

The expected API of UriQuery (annotated with the DOM URL API it uses) is:
``` dart
/// Representation the query part of a URI.
///
/// A query is a set of key/value pairs, the "entries" of the query.
/// The [UriQuery] gives access to individual entries or to the key/value mapping.
///
/// The [parse] method parses URL-form-encoded query parameters, and the [toString]
/// method creates a URL-form-encoded representation of the query. 
/// All other methods operate on unencoded strings.
abstract class UriQuery {
  /// Creates a new query with a single value for each key.
  factory UriQuery([Map<String, String> entries]) => 
      (new UriQueryBuilder()..addEntries(entries.entries)).toQuery()

  /// Creates a new query which can have multiple values for each key.
  factory UriQuery.multi(Map<String, Iterable<String>> entries) {
    var builder = new UriQueryBuilder();
    entries.forEach(builder.addAll);
    return builder.toQuery();
  }

  /// Creates a new query with the provided entries.
  factory UriQuery.fromEntries(Iterable<MapEntry<String, String>> entries) => 
    (new UriQueryBuilder()..addEntries(entries)).toQuery();

  /// Parses a URI query string in `application/x-www-form-urlencoded` format.
  ///
  /// The [queryString] may be preceded by a leading `?` character, in which case
  /// that character is not considered part of the query.
  ///
  /// Throws a [FormatException] if parsing fails.
  external static UriQuery parse(String queryString);

  /// Tries to parse [queryString] as a [UriQuery].
  ///
  /// Same as [parse] but returns `null` when the parsing fails.
  external static UriQuery tryParse(String queryString);

  /// The encoded text of the query, as it would be included in a URL.
  /// 
  /// Contains all entries separated by `&` characters, and each key and
  /// value separated by a `=` character. The individual keys and values are
  /// are URL-form-encoded. There is no leading question mark.
  /// If the query has no entries, the returned strings is empty.
  String toString();  // URL.stringifier

  /// Whether the query contains an entry with [key] as key.
  ///
  /// The provided [key] should not be encoded. The keys of the query object
  /// are decoded before being compared to [key].
  bool contains(String key);  // URL.has

  /// Look up the value, if any, of a key,
  ///
  /// Returns `null` if the key is not present or has no value.
  /// Otherwise returns the first value associated with key.
  String operator[](String key);  // URL.get

  /// The keys of entries in the query.
  ///
  /// Each key is only reported once, even if it occurs multiple times
  /// with different values.
  Iterable<String> get keys; // iterate entries, return key.

  /// All values associated with [key].
  ///
  /// If [key] occurs more than once once, this allows access to all the values.
  Iterable<String> values(String key);  // URL.getAll

  /// Take an action for each entry in the query.
  ///
  /// If a key occurs multiple times, the [action] is taken for each instance,
  /// irrespectively of the value (or absence of value).
  /// The key and value are decoded before being passed to [action].
  void forEach(void action(String key, String value));  // iterate entries

  /// Each key/value combination as a [MapEntry].
  ///
  /// The [Object.toString] of the entry is the original query text for
  /// the entry.
  Iterable<MapEntry<String, String>> get entries;  // iterate entries

  /// Exposes the keys and first-values of each key as a map.
  Map<String, String> asMap();  // Wrapper using has/[]

  /// Exposes the keys and all values of each key as a map.
  Map<String, Iterable<String>> asMultiMap();  // Wrapper using has/getAll
}

/// Builder for [UriQuery] objects.
///
/// Builds a sequence of key or key/value entries.
/// The sequence is retained in insertion order.
abstract class UriQueryBuilder {
  UriQueryBuilder([UriQuery initialContent]) = _UriQueryBuilder;

  // Returns a [UriQuery] with the current entries of this builder.
  //
  // Clears this builder as if calling [clear].
  UriQuery toQuery();

  /// Whether the query contains any entries for [key].
  bool contains(String key);  // URL.has

  /// All the values associated with [key].
  ///
  /// If an entry for key has no value, the `null` value is used instead.
  List<String> values(String key);  // URL.getAll+toList

  /// All the entries of the query.
  ///
  /// Entries with not value are represented by a [MapEntry] with a null value.
  List<MapEntry<String, String>> get entries;  // Iterate entries

  /// Sets [value] as the only value for [key].
  ///
  /// Removes all existing entries for [key] and adds [key]/[value] as
  /// the only entry.
  ///
  /// If [value] is `null`, the added entry has no value.
  void operator []=(String key, String value);  // URL.set

  /// Sets [values] as the only values for [key].
  ///
  /// Removes all existing entries for [key] and adds [key]/value as
  /// an entry for each value in [values].
  ///
  /// If any of [values] are `null`, the corresponding entry has no value.
  void setAll(String key, Iterable<String> values); // Url.remove+Url.append

  /// Adds an entry for [key] with [value] as value.
  ///
  /// Retains all previous entries for [key] and adds one more.
  ///
  /// If [value] is omitted or `null`, an entry with no value is added.
  ///
  /// The entry is added after all existing entries.
  void add(String key, [String value]);  // URL.append

  /// Adds multiple entries for [key].
  ///
  /// If any of [values] are `null`, the corresponding entry has no value.
  /// This retains all previous entries for [key] and adds more.
  ///
  /// The entries are added after all existing entries, in iteration order.
  void addAll(String key, Iterable<String> values);  // URL.append

  /// Adds multiple entries.
  ///
  /// For each entry in [entries], add that key/value entry to the query.
  /// If a value is `null`, the corresponding query entry has no value.
  ///
  /// The entries are added after all existing entries, in iteration order.
  void addEntries(Iterable<MapEntry<String, String>> entries);  // URL.append

  /// Sorts the current entries by key.
  ///
  /// Retains the current order of values for each key.
  ///
  /// If [compareKey] is omitted, keys are sorted lexically by
  /// [String.compareTo].
  // Use URL.sort if available and compareKey == null, otherwise manual
  // by sorting entries and reinserting.
  void sortKeys([int compareKey(String key1, String key2)]);

  /// Sorts all the entries.
  ///
  /// If [compare] is omitted, entries are first sorted by key, and then the
  /// values for each key are sorted, all ordered by [String.compareTo]
  // Sort manually, no URL support.
  void sort([
      int compare(MapEntry<String, String> e1, MapEntry<String,String> e2)]);

  /// Removes all entries.
  void clear();  // replace internal object

  /// Removes all entries for the provided [key].
  ///
  /// Has no effect if the key does not occur in the query.
  void remove(String key);  // URL.delete

  /// Removes a single entry.
  ///
  /// If the same entry occurs more than once in the query, only the
  /// first such entry is removed.
  ///
  /// Has no effect if this particular key/value pair does not occur in the
  /// query.
  void removeEntry(String key, String value);  // Completely manual.

  /// Returns a string representation of the query.
  ///
  /// The representation can be used as the query-part of a URI.
  /// It includes a leading `?` if there is at least one entry in the query.
  /// This is the same string returned by toQuery().toString().
  String toString();  // URL.stringifier
}
```

Other than the `UriQuery` change, all but one of the remaining changes to the `Uri` class do not affect the API.
* Only a list of recognized schemes are considered as having an authority part (the WHATWG URL "special" URLs). We add `package:` as a special scheme that the Dart Uri class recognizes.
* The `resolve` and `resolveUri` methods will only work on URIs with a scheme, not on URI references without a scheme. This is how the WHATWG URL works too, and it differs from the current implementation which does a best-effort attempt at merging. It might be possible to remove this restriction, but at the cost of implementing it ourselves even in a browser. 
* The `isAbsolute` getter was never useful as written. It reflects a property of the URI specification that isn't actually useful to users. It is changed to do what most users expect: Say whether the `Uri` instance is a full URI with a scheme, not a relative URI reference.
* The replace method is renamed to `with` (which we will change to not be a reserved word in Dart 2). You can write:
  ``` dart
  var uri = Uri.parse("http://example.org/path?w=dart");
  var secureUri = uri.with(scheme: "https");
  ```
* The static helper methods for doing to do various kinds of escaping will be aligned to exactly match the escapes available in a browser: The ECMAScript `escapeURI` and `escapeURIComponent` methods and the escaping done by `URLSearchParams` objects.
* The `toFilePath` method is removed. It requires the URI implementation to know whether it's on a Windows based platform, which is not something the system should know or care about outside of the `dart:io` library. We will make sure that this functionality is still available in the `dart:io` library.
* The `==` and `hashCode` is defined in terms of the non-normalized URI representation. You may want to normalize

> The most common use of `Uri` is its parser: `Uri.parse`. For the most part (except our tests), the provided string can be easily parsed and doesn't encounter corner cases. For the majority of users, this change is thus non-breaking.
> The `UriQuery` change is also breaking. The class provides an indexing operator with makes its use very similar to the `Map` that was there before, but there will be cases where the upgrade requires some effort.

#### Completeness
The `bool` class now features the non-shortcutting versions of `&&` and `||`: `&` and `|`. It also has the exclusive-or (`^`) operator (equivalent to `b1 != b2` for non-null boolean values). Having them as operators makes it possible to use them in compound assignments: `someBool &= alwaysComputeSomeBool` without shortcutting the right-hand side.

The `Future` and `Stream` class from `dart:async` are now also exposed from `dart:core`. This means that the return types of `async` and `async*` functions can now be expressed without importing `dart:async` first.

The `Duration` class now has a static `Duration.parse` method, which will (at least) parse the output of its own `toString`, ISO-8601 durations, and the output of Go durations. Similarly to all other `parse` methods there will be a `tryParse` next to the method. See below for more details on `tryParse`.

The `Invocation` class can now be instantiated. We added the following constructors:
``` dart
  const Invocation.method(Symbol memberName, {List<Object> positionalArguments,
      Map<Symbol, dynamic> namedArguments, List<Type> typeArguments});

  const Invocation.getter(Symbol memberName);

  /// The provided [setterName] should have a trailing '='.
  const Invocation.setter(Symbol setterName, Object value);
```
We also added a `typeArguments` getter for generic types.

While cleaning up the `Invocation` class we also decided to improve its `toString` message. This improvement will probably only hit the VM/Flutter, since dart2js and DDC don't have as much information available as the VM does.

The `Function.apply` function now takes optional generic types, and the optional parameters are named instead of positional:
``` dart
external static apply(Function function, List positionalArguments,
      {Map<Symbol, dynamic> namedArguments, List<Type> typeArguments});
```

We have added a `Symbol.empty` constant and will add all operators as static constants on `Symbol`. (We haven't decided on the names yet, and would appreciate feedback). Also, we now give direct access to the name of a symbol through the `name` getter. When minified the name getter will return the *minified* name. This is in response to users doing `String.substring` on the `toString` of `Symbol` instances, which was already returning the minified symbol.

The `StringSink` class (and as a consequence the `StringBuffer class`) now also contains `addCharCodes`. It already had `addCharCode`.

In the `RegExp` class the `firstMatch`, `hasMatch` and `stringMatch` functions now take optional `start` arguments. This avoids costly `substring` operations.

> Except for the additional methods in `StringSink` and the change of the optional parameter type of `Function.apply`, none of the changes in this section are breaking to non-subtypes.

#### Consistency
All `parse` functions received a corresponding `tryParse` function that returns `null` when the input is invalid. The `onError` arguments (positional or named) will be removed. This change affected:
* `double.parse`: was an optional positional argument.
* `DateTime.parse`.
* `Duration.parse`: didn't exist before (see above).
* `Uri.parse`.

The `tryParse` function returns `null` when the input is invalid, which can be nicely combined with the `??` operator: `int.tryParse(someString) ?? 0`.

> Removing the optional `onError` functions is breaking, but they are easy to find (since these are static calls), and generally easy to fix by changing them to `tryParse` calls.

#### Convenience
The `UnsupportedError` makes the message argument optional. In most cases the stack trace already identifies the unsupported functionality, and providing a message argument feels redundant.

We finally provide means to combine hashcodes. As a starting point we added `Object.hash` as a static function. It currently takes up to ten arguments (of which the last 9 are optional). Once we have rest-arguments we will change the function to take an arbitrary number of arguments. At that point it will also be possible to spread lists of objects.

Strings will support UTF-8, UTF-16 and UTF-32 conversions directly. For simple conversions, one doesn't need to use `dart:convert` anymore. The following constructors and methods are now part of `String`.

``` dart
  factory String.fromUtf8(List<int> codeUnits, [int start = 0, int end]);
  factory String.fromUtf16(List<int> codeUnits, [int start = 0, int end]);
  factory String.fromUtf32(List<int> codeUnits, [int start = 0, int end]);

  Uint8List toUtf8([int start = 0, int end]);
  Uint16List toUtf16([int start = 0, int end]);
  Uint32List toUtf32([int start = 0, int end]);
```

> All of these changes are non-breaking.

#### Cleanups
Removed `AbstractClassInstantiationError` which can't happen in Dart 2.0 anymore.

The `TypeError` is not an `AssertionError` anymore.

Removed the `IntegerDivisionByZeroException`. It never really was an `Exception`. If an integer division receives `0` it should just throw an `ArgumentError`.

The `NoSuchMethodError` class now takes an `Invocation` as argument. This makes it easier to construct from within `noSuchMethod` functions, and makes it possible to reuse the newly introduced Invocation constructors (see above).

We removed the `group()` method in Match. It was an alias for the indexing operator. This means that `match?.group(5)` is not possible anymore, but we prefer fixing this by providing a null-aware index access in a future language change.

We also changed the `groups` function so that the `groupIndices` are optional. This means that `match.groups()` now returns a list with all matches (including the full match as 0th entry).

We moved the `BidirectionalIterator` from `dart:core` to `dart:collection`.

> In theory, users could use the fact that TypeError implemented AssertionError. This is highly unlikely, though.
>
> Removing the `IntegerDivisionByZeroException` breaks programs that relied on it. However, in the browser this exception was never thrown (since dart2js couldn't know if the argument was a `0` or `0.0`). Also, as indicated by the replacement with `ArgumentError`, we consider a division by `0` as an error which should not happen in programs.
>
> Changing the constructor of `NoSuchMethodError` is breaking. It can be statically detected, though (since constructors can not be torn off), and the fix is very simple. Few developers instantiate their own `NoSuchMethodError`s, so the change won't affect many users.
>
> The removal of group in Match potentially affects more users, but the work-around is very simple.

#### Types
The `Object.runtimeType` is being removed and replaced by `Type.of(object)`. The idea of being able to emulate other classes by changing the `runtimeType` sounds interesting, but since Dart doesn't support any means to also manipulate the `is` operator, its uses are extremely limiting. The static `Type.of` function is less error-prone and more efficient for compilers.

In addition, we intend to make `Type` more useful by making it a generic class, and by adding methods to compare types among each other:
``` dart
abstract class Type<T> {
  static Type<S> of<S>(S Object) {}

  /**
   * Returns whether [other] is a subtype of this.
   */
  bool isSubtypeOf(Type other);
  bool isSupertypeOf(Type other);

  /**
   * Returns whether this class is the type of [o].
   */
  bool accepts(Object o);
}
```

The generic argument to `Type` is still pending language changes. Currently, a generic function type (like the type of the tear-off of `List.map`) is not allowed to be used as a generic argument. This would make `Type.of(list.map)` not work, or infer `Type<Function>` for that expression.

> For most cases, the .runtimeType should just be replaced by the static call to Type.of.
>
> The change can be more breaking, if users overwrote the runtimeType getter. In that case it's necessary to refactor the code on a case-by-case basis.
>
> When compiling with dart2js the necessary information to make isSubtypeOf and isSupertypeOf work might increase the code size. This can be mitigated in 3 ways:
> By not using the methods when compiling to the web. (A short-term solution).
> By providing a flag to disable relationships of DOM classes (which would be the reason for the biggest chunk of the size increase).
> By optimizing the inheritance-relationship in dart2js. The implementation of Types in dart2js is sub-optimal, and should be reworked (also for the strong type system).

#### DateTime
We made `DateTime` significantly better for use as dates. Here is the new API. (All methods without dartdocs have not changed).

``` dart
class DateTime implements Comparable<DateTime> {
  // All constants are lowercase now.
  static const int monday = 1;
  static const int tuesday = 2;
  static const int wednesday = 3;
  static const int thursday = 4;
  static const int friday = 5;
  static const int saturday = 6;
  static const int sunday = 7;
  static const int daysPerWeek = 7;

  static const int january = 1;
  static const int february = 2;
  static const int march = 3;
  static const int april = 4;
  static const int may = 5;
  static const int june = 6;
  static const int july = 7;
  static const int august = 8;
  static const int september = 9;
  static const int october = 10;
  static const int november = 11;
  static const int december = 12;
  static const int monthsPerYear = 12;


  final bool isUtc;

  DateTime(int year,  [int month = 1, int day = 1, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0]);

  /**
   * Constructs a [DateTime] instance with the current date.
   *
   * The resulting [DateTime] is in UTC and has the time set to 00:00.
   */
  factory DateTime.today();

  /**
   * Constructs a [DateTime] for the given date.
   *
   * The resulting [DateTime] is in the UTC and has the time set to 00:00.
   */
  DateTime.date(int year, int month, int day);

  DateTime.utc(int year,  [int month = 1, int day = 1, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0]);

  DateTime.now() : this._now();

  // Improved to accept RFC1123 format (and more of RFC 3399).
  // Now errors, if the entries are out of range (like a month value of 13).
  static DateTime parse(String formattedString);

  /**
   * Constructs a new [DateTime] instance based on [formattedString].
   *
   * Same as [parse] but returns `null` if the [formattedString] is invalid.
   */
  static DateTime tryParse(String formattedString);

  DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch, {bool isUtc: false});
  DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch, {bool isUtc: false});

  bool operator ==(other);
  bool isBefore(DateTime other);
  bool isAfter(DateTime other);
  bool isAtSameMomentAs(DateTime other);
  int compareTo(DateTime other);

  DateTime toLocal();
  DateTime toUtc();

  /**
   * Returns this instance suitable for date computations.
   *
   * The resulting DateTime is in the UTC timezone and has the time set to 00:00.
   */
  DateTime toDate() => new DateTime.date(year, month, day);

  /**
   * Returns a [DateTime] instance with the provided arguments replaced by the
   * new values.
   *
   * The returned DateTime is constructed as if the [DateTime] constructor was
   * called. This means that over and underflows are allowed.
   */
  DateTime with({int year, int month, int day, int hour, int minute, int second,
      int millisecond, int microsecond, bool isUtc});

  String toIso8601String() {

  /**
   * Returns a string following the RFC 1123 specification.
   *
   * This format is used in cookies.
   * 
   * It is called `toUTCString` in EcmaScript. 
   */
  String toRfc1123String() {
    // https://stackoverflow.com/questions/25658897/is-utc-a-valid-timezone-name-for-rfc-1123-specification
    // TODO(floitsch): Tue, 05 Sep 2017 13:43:53 GMT.
    return "TODO";
  }

  /**
   * Returns a new [DateTime] instance with the provided arguments added to
   * to [this].
   *
   * ```
   * var today = new DateTime.now();
   * var fiftyDaysFromNow = today.add(new Duration(days: 50));
   * ```
   *
   * Be careful when working with dates in local time and durations. A
   * `new Duration(days: 3)` is actually `3 * 24 * 60 * 60` seconds. Use
   * the [days] named argument if you want to ensure that the resulting time is
   * still the same.
   *
   * Adding a specific number of months will clamp the day, if the resulting
   * day would not be in the same month anymore:
   *
   * ```
   * new DateTime(2017, 03, 31).add(months: 1); // => 2017-04-30.
   * ```
   *
   * Days are added in such a way that the resulting time is the same (if that's
   * possible). When daylight saving changes occur, adding a single [day] might
   * add as little as 23, and as much as 25 hours.
   *
   * The arguments are added in the following way:
   * * Compute a new clock-time using [microseconds], [milliseconds], [seconds],
   *   [minutes], [hours]. At this time, days are assumed to be 24 hours long
   *   (without any daylight saving changes). If any unit overflows or
   *   underflows, the next higher unit is updated correspondingly.
   * * Any over- or underflow days are added to the [days] value.
   * * A new calendar date is computed by adding 12 * [years] + [months] months 
   *   to the current calendar date. If necessary, the date is then clamped.
   * * Once the date is valid, the updated [days] value is added to the
   *   calendar date.
   * * The new date and time values are used to compute a new [DateTime] as if
   *   the [DateTime] constructor was called. Non-existing or ambiguous times
   *   (because of daylight saving changes) are resolved at this point.
   * * Finally, the [duration] is added to the result of this computation.
   *
   * All arguments may be negative.
   * ```
   * var tomorrowTwoHoursEarlier = date.add(days: 1, hours: -2);
   * var lastDayOfMonth = date.with(day: 1).add(month: 1, days: -1);
   * ```
   */
  // All values default to 0 (or a duration of 0).
  DateTime add({int years, int months, int days, int hours,
    int minutes, int seconds, int milliseconds, int microseconds,
    Duration duration});

  /**
   * Returns a new [DateTime] instance with the provided arguments subtracted
   * from [this].
   *
   * This is equivalent to calling [add] with all given arguments negated.
   */
  external DateTime subtract({int years, int months, int days, int hours,
    int minutes, int seconds, int milliseconds, int microseconds,
    Duration duration});

  Duration difference(DateTime other);

  int get millisecondsSinceEpoch;
  int get microsecondsSinceEpoch;
  String get timeZoneName;
  Duration get timeZoneOffset;

  int get year;
  int get month;
  int get day;
  int get hour;
  int get minute;
  int get second;
  int get millisecond;
  int get microsecond;
  int get weekday;

  /**
   * Returns which day of the year this DateTime represents.
   *
   * The 1st of January returns 1.
   */
  int get dayInYear;
}
```

The reason for the breaking change of add is that we want to make date-time manipulations easier in face of daylight savings. Currently, a common mistake is to write `dt.add(const Duration(days: 1))` and to expect a new date on the following day with the same time. However, this is not true when there is a daylight savings change.

By giving easy access to `add(days: 1)` we make it easier for users not to run into this trap. It is also easier to read.

The alternative would be to add a different `addX` method (with the same named arguments), or to add separate `addDays`, `addMonths` ... methods. This is the approach that, for example, C# took.

> This change is breaking in two ways:
> subtypes have to add the new methods.
> the add method now takes named arguments instead of the one positional `Duration` argument.
> Users of the `add` method now need to prefix their argument with "duration:". We feel that the benefits of the new API is worth the cost of migration.

#### Collections
Most of the collection changes are additive. They are breaking in that implementers of these class interfaces now need to provide the same functionality (unless they get them for free with our mixins or base classes).

##### Iterable
Since `List` and `Set` (as well as `Queue` from `dart:collection`) are subtypes of Iterable all the following changes apply to these interfaces as well.

We added some methods that make it easier to type programs correctly, now that dynamic can't be used as escape-hatch anymore:

``` dart
  /**
   * Returns a new lazy [Iterable] with all elements that are of type [T].
   *
   * All elements that are not of type [T] are omitted.
   */
  Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);

  /**
   * Returns the elements of this iterable as an `Iterable<T>`.
   * 
   * Returns a new lazy [Iterable] that wraps this iterable 
   * and enforces the provided generic type [T].
   *
   * Whenever this iterable returns or takes a [T] inserts checks to ensure
   * that the new contract is verified.
   * Subclasses may choose to provide a cast operation that returns an instance
   * of the subtype with the new type argument. 
   * The classes [List], [Set] and [Queue] all do so.
   */
  Iterable<T> cast<T>() => new CastIterable<T>(this);
```

A call to cast wraps the receiver and provides the requested typed interface. Subtypes are encouraged to provide matching types (`List` provides a `List`, `Set` a `Set`, ...).

The wrapper should avoid returning wrapped results when it creates a new object. For example, the `toSet()` method of the `CastIterable` should not be implemented as follows:
``` dart
Set<E> toSet() {
  return _wrapped.toSet().cast<E>();
}
```

This is not just a performance question, but also has semantic impact, since checks are delayed even more, and the user would expect `listOfInt.cast<num>().toList()..add(3.14)` to succeed. This is only true for operations that are already eager. Lazy operations should wrap:
``` dart
Iterable<E> skip(int count) {
  return _wrapped.skip(count).cast<E>();
}
```
This is necessary to support infinite iterables.

For convenience and completeness we have added a few (often RX inspired) methods:
``` dart
  /**
   * Combines the provided [iterables] by taking one of each and grouping them
   * in a list.
   */
  static Iterable<List<T>> zip<T>(Iterable<Iterable<T>> iterables);

  /**
   * Creates a new iterable from this stream that discards some elements.
   *
   * Same as:
   *
   * ```
   *where((event) => !test(event))
   * ```
   */
  Iterable<T> whereNot(bool test(T event)) {
    return new WhereIterable(this, test, invert: true);
  }

  /**
   * Groups the elements of this iterable according to the [key] function.
   */
  Map<K, List<E>> groupBy<K>(K key(E element)) {
    var result = <K, List<E>>{};
    for (var e in this) {
      result.putIfAbsent(key(e), () => <E>[]).add(e);
    }
    return result;
  }

  /**
   * Combines a sequence of values by repeatedly applying [combine] and emits
   * every intermediate result.
   *
   * Similar to [Iterable.fold], except that the intermediate results are
   * emitted on the returned [Iterable].
   *
   * If [emitInitialValue] is `true` also emits the [initialValue] 
   * as first element.
   */
  Iterable<S> foldEmit<S>(S initialValue, S combine(S previous, E element),
      { bool emitInitialValue: false });

  /**
   * Reduces a collection by iteratively combining elements
   * of the collection using the provided function. Each intermediate result
   * is emitted to the result iterable.
   *
   * This function is similar to [reduce] but emits the intermediate results.
   */
  Iterable<E> reduceEmit(E combine(E previous, E element));

  /**
   * Returns the concatenated iterable of this [Iterable] and [other].
   *
   * The returned [Iterable] is lazy, and only starts iterating over
   * [this] and [other] when needed.
   */
  Iterable<E> followedBy(Iterable<E> other);
```

Extensions methods (if available in Dart) could provide this functionality, but 1. Dart doesn't have extension methods, and 2. they would not allow as efficient implementations. For example, the `.followedBy` implementation of a `List` will be different than the one of `Iterable`.

The `whereNot` is clearly redundant with `where`. We have included for similar reasons as `isNotEmpty`: it is a relatively common operation and makes the code much easier to read. Especially with tear-offs the code becomes simpler:

``` dart
it1.where((x) => !mySet.contains(x));  // Old.
it1.whereNot(mySet.contains);  // New.
```

Implementation-wise, the `whereNot` functionality would reuse the same class as `where` and would thus only add minimal code.

Finally, we added the missing `orElse` in `singleWhere`. This makes the function consistent with `firstWhere` and `lastWhere`: `E singleWhere(bool test(E element), {E orElse()})`.

> Due to the existing `IterableMixin` and `IterableBase` we expect this change to be less painful than it looks. Almost all classes that don't use these two classes only forward or wrap an existing `Iterable`. As such the migration should be easy.

#### List and Set
Lists and sets only needed few changes (in addition to `Iterable` changes). Both had similar cleanups for their constructors: `List.from` and `Set.from` now take typed Iterables:
``` dart
factory List.from(Iterable<E> elements, {bool growable: true});
Set.from(Iterable<E> elements) = LinkedHashSet<E>.from;
```

`List.from` is frequently used to change the generic type of an existing `List` instance. In these cases, one will need `cast` or `castCopy` as a replacement.
> The change is consistent with other strongifications of the libraries, though.

##### List
As promised we added the `+` operator to lists. One can finally write `list1 + list2`.

We added `copy` methods to List:
``` dart
  /**
   * Creates a new list of the same type as this list.
   *
   * The new list contains the same elements as this list.
   * If [start] and [end] are provided, the new list will only contain
   * the elements from [start] to, but not including, [end],
   * and the length of the list match the new number of elements.
   *
   * The provided range, given by [start] and [end], must be valid.
   */
  List<E> copy([int start = 0, int end]);

  /**
   * Creates a new list of the same kind as this list.
   *
   * The new list will have [T] as element type.
   *
   * The new list contains the same elements as this list.
   * If [start] and [end] are provided, the new list will only contain
   * the elements from [start] to, but not including, [end],
   * and the length of the list match the new number of elements.
   *
   * All the elements of the copied range must be assignable to [T].
   *
   * The provided range, given by [start] and [end], must be valid.
   *
   * Some kinds of lists cannot be created with arbitrary types.
   * For example, a [Uint8List] cannot be copied as a list with
   * an element type different from [int].
   * In such a case, the list implementation must document what
   * it does instead.
   */
  List<T> castCopy<T>([int start = 0, int end]);
```

These would mean that there are now 4 ways to create a copy of a `List`:
1. `copy`,
2. `toList`,
3. `new List.from()`,
4. `sublist`.

Clearly, that's not a good idea. We are still investigating the best solution to this problem. We like `copy`, because it works for other classes (like `Map`, `Set` and `Queue`) and has a corresponding `castCopy` (which is necessary to correctly implement `.cast<T>().toList()`).

We are debating whether we should deprecate `sublist` (which can be fully implemented with `copy`), and then make `toList()` just a shorthand for `new List.from()`. This makes sense, since `toList()` takes a named argument `growable` which only applies to the core library's `List` implementation.

For `Set`, where a similar problem arises, this would be a breaking change: so far we have recommended that `toSet()` maintains the same properties as the `Set` it comes from. For example, `identitySet.toSet()` currently is supposed to return again an identity-set.

We added idiomatic ways to set the first and last element of the list without using the index operator:
``` dart
  set first(E newValue);  // { this[0] = newValue; } + throw if empty.
  set last(E newValue);  // { this[length - 1] = newValue; } + throw if empty.
```

`List` already had functions to search for elements that satisfy specific predicates (`firstWhere`, and `lastWhere`), but now we added functions that return the indices of the found element. These are consistent with indexOf found in List.

``` dart
  /**
   * Returns the first index in the list that satisfies the provided [predicate].
   *
   * Searches the list from index [start] to the end of the list.
   * The first time an object `o` is encountered so that `predicate(o)` is true,
   * the index of `o` is returned.
   *
   * ```
   * List<String> notes = ['do', 're', 'mi', 're'];
   * notes.indexWhere((note) => note.startsWith('r'));       // 1
   * notes.indexWhere((note) => note.startsWith('r'), 2);    // 3
   * ```
   *
   * Returns -1 if [element] is not found.
   * ```
   * notes.indexWhere((note) => note.startsWith('k'));    // -1
   * ```
   */
  int indexWhere(bool predicate(E x), [int start = 0]);

  /**
   * Returns the last index in the list that satisfies the provided [predicate].
   *
   * Searches the list from index [start] to 0.
   * The first time an object `o` is encountered so that `predicate(o)` is true,
   * the index of `o` is returned.
   *
   * ```
   * List<String> notes = ['do', 're', 'mi', 're'];
   * notes.lastIndexWhere((note) => note.startsWith('r'));       // 3
   * notes.lastIndexWhere((note) => note.startsWith('r'), 2);    // 1
   * ```
   *
   * Returns -1 if [element] is not found.
   * ```
   * notes.lastIndexWhere((note) => note.startsWith('k'));    // -1
   * ```
   */
  int lastIndexWhere(bool predicate(E x), [int start = 0]);
```
An alternative name would be `firstIndexWhere`, which would be consistent with `firstWhere`. Conceptually, `indexWhere` is the combination of `indexOf`/`lastIndexOf` and `firstWhere`/`lastWhere`. We decided to align it with `indexOf`, rather than `firstWhere`.

We are also honoring a request from `ObservableList` to make swapping a single operation (instead of two indexing operations), by adding `swap` methods. In many cases they are also more readable.

``` dart
  /**
   * Swaps the elements at [index1] and [index2].
   *
   * Equivalent to
   * ```
   * var tmp = this[index1];
   * this[index1] = this[index2];
   * this[index2] = tmp;
   * ```
   */
  void swap(int index1, int index2);

  /**
   * Swaps the ranges of elements at [start]..[end] with the ones located at
   * [otherStart] (of the same length).
   *
   * The two ranges must not overlap.
   */
  void swapRange(int start, int end, int otherStart);
```

We changed the signature of `fillRange` to require a `fillValue`. The argument was optional before and would fill in `null`s if not given. This works poorly with non-nullable types, is almost never needed, and reduces readability when used..

> All `List` member changes, except `fillRange` are non-breaking except for subtypes. For `fillRange` users just need to pass in an additional null.

##### Set
`Set` loses the lookup method. It is difficult to implement for some Sets and should just be replaced by a `Map`.

We have added the `copy` and `castCopy` methods (similar to `List`). The `copy` method maintains the same type as the receiver. In particular, it keeps the same parametrization. A copy of an identity set still is an identity set (`(new Set.identity()..add(x)).copy()` is again an identity set). With the `empty` argument, this makes it possible to create an empty copy of the same type.

``` dart
Set<E> copy({bool empty = false});
Set<T> castCopy<T>({bool empty = false});
```

Similar to the `List` case (and partially discussed there), we now have three ways to create a copy of a set: `copy`, `toSet()` and `new Set.from()`. Our current thinking is that `toSet()` is just an alias for `new Set.from()` and `copy` maintains the parametrization of the receiver. This would be a breaking change, though. We have to investigate more.  (Feedback welcome).

> We recommend to switch from `Set` to a `Map` for cases where users want to read a value back out of the collection. In most cases this should be trivial, but there could be cases where this is hard.

#### Map
##### Consistency
Similar to `List` and `Set`, the `Map.from` constructor now takes a typed argument, and we added `copy`, `cast` and `castCopy` methods.

``` dart
Map.from(Map<K, V> other);  // Now requires other to have the correct type.

Map<K, V> copy({bool empty = false});
Map<K2, V2> cast<K2, V2>();
Map<K2, V2> castCopy<K2, V2>({bool empty = false})
```

> The `Map.from` is, according to our research, used quite often, but it's not clear how often the intent is to just create a copy. We hope few uses are for casting.

##### Completeness and Convenience
The Map class was relatively barebones in Dart 1.x. We now added many additional methods that should make work with Maps much more pleasant. Most of the new functions rely on an additional class MapEntry. We decided to make the MapEntry class immutable.

``` dart
class MapEntry<K, V> {
  final K key;
  final V value;
  const MapEntry(this.key, this. value);
}
```

The added functions are:
``` dart
 factory Map.fromEntries(Iterable<MapEntry<K, V>> entries);

  /**
   * The map entries of [this].
   */
  Iterable<MapEntry<K, V>> get entries;
  /**
   * Returns a new map where all entries of this map are transformed by
   * the given [f] function.
   */
  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> f(K key, V value));

  /**
   * Adds all key-value pairs of [newEntries] to this map.
   *
   * If a key of [other] is already in this map, its value is overwritten.
   *
   * The operation is equivalent to doing `this[entry.key] = entry.value` for each
   * [MapEntry] of the iterable.
   */
  void addEntries(Iterable<MapEntry<K, V>> newEntries);

  /**
   * Updates the value for the provided [key].
   *
   * Returns the new value of the key.
   *
   * If the key is present, invokes [update] with the current value and stores
   * the new value in the map.
   *
   * If the key is not present and [ifAbsent] is provided, calls [ifAbsent]
   * and adds the key with the returned value to the map.
   *
   * It's an error if the key is not present and [ifAbsent] is not provided.
   */
  V update(K key, V update(V value), {V ifAbsent()});

  /**
   * Updates all values.
   *
   * Iterates over all entries in the map and updates them with the result
   * of invoking [update].
   */
  void updateAll(V update(K key, V value));

  /**
   * Removes all entries of this map that satisfy the given [predicate].
   */
  void removeWhere(bool predicate(K key, V value));

  /**
   * Returns the value of the given [key], or the result of invoking [ifAbsent]
   * if the key is not present.
   *
   * By default [ifAbsent] returns null.
   */
  V lookup(Object key, {V ifAbsent()});
```

> All of these methods only break subtypes.

## dart:async
The `dart:async` library will see three major changes:
1. it will allow more synchronous uses of the StreamController and Completer classes.
2. it will remove the distinction of single-subscription and broadcast-streams, and let the event-provider (generally a `StreamController`) decide how it should handle multiple subscriptions.
3. More functionality and cleanups on Stream and StreamSubscription.

Other improvements and cleanups reduce the number of classes and fix a bad behavior in the Timer class.

### Synchronous Uses
Most of the `dart:async` changes are in response to unexpected and unsupported uses of our libraries. Despite our best efforts, developers used our streams and futures in synchronous ways far more often than expected. One reason for this is that stream controllers were either synchronous or asynchronous, so if you want to emit any event synchronously, you had to use a synchronous controller and emit all events synchronously. 

With Dart 2.0, we remove a number of restrictions around streams. This simplifies the library design and implementation because the restrictions were encoded in the class hierarchy or individual class API, or it affected the implementation.

We allow the same stream controller to emit events both synchronously and asynchronously, and we handle the interaction between the two so users won't have to do it. This provides more flexibility and removes one of the two classes.

As a consequence, we now provide both methods to `StreamController`s (and symmetrically to `Completer`s). The user now has to decide which method to use to inform the listeners. 

Concretely, the interfaces for `Completer` and `StreamController` now look as follows (with dartdocs removed if it they didn't change substantially):

``` dart
abstract class Completer<T> {
  factory Completer() => ...;

  Future<T> get future;

  void complete([FutureOr<T> value]);

  /**
   * Completes [future] synchronously with the supplied value.
   *
   * Listeners on futures expect to be called back asynchronously. A synchronous
   * completion of the future could violate the user's assumptions. If in
   * doubt prefer to use [complete] to make it easier for users to predict at
   * which time a future can complete.
   *
   * Calling [complete], [completeSync] or [completeError] must be done at most
   * once.
   *
   * All current listeners on the future are informed about the value immediately,
   * future listeners will be notified asynchronously.
   */
  void completeSync([T value]);

  void completeError(Object error, [StackTrace stackTrace]);

  bool get isCompleted;
}

abstract class StreamController<T> implements StreamSink<T> {
  Stream<T> get stream;

  // Note that there is no `sync` named argument anymore.
  // Also note that `onCancel` now returns a `FutureOr<void>`.
  factory StreamController(
      {void onListen(),
      void onPause(),
      void onResume(),
      FutureOr<void> onCancel()}) { ... }

  // Same: no `sync` named argument anymore.
  factory StreamController.broadcast({void onListen(), void onCancel()}) {
     return new _SyncBroadcastStreamController<T>(onListen, onCancel);
  }

  void set onListen(void onListenHandler());

  void set onPause(void onPauseHandler());

  void set onResume(void onResumeHandler());

  void set onCancel(onCancelHandler());

  StreamSink<T> get sink;

  /**
   * Returns a view of this object that exposes the synchronous methods
   * of this controller as a [StreamSink].
   */
  StreamSink<T> get syncSink;

  bool get isClosed;

  bool get isPaused;

  bool get hasListener;

  void add(T event);

  /**
   * Sends a data [event] synchronously.
   *
   * If this controller has delayed events pending, this event is delayed too. 
   * This ensures that events are received in order.
   *
   * If this controller has multiple listeners, and is already emitting events
   * synchronously, delays sending this event. This ensures that all listeners
   * receive the events in order.
   */
  void addSync(T event);

  void addError(Object error, [StackTrace stackTrace]);

  /**
   * Sends or enqueues an error event synchronously.
   *
   * If [error] is `null`, it is replaced by a [NullThrownError].
   *
   * If this controller has delayed events pending, this event is delayed too. This
   * ensures that events are sent in order.
   *
   * If this controller has multiple listeners, and is already emitting events
   * synchronously, delays sending this event. This ensures that all listeners
   * receive the events in order.
   */
  void addErrorSync(Object error, [StackTrace stackTrace]);

  Future close();

  /**
   * Closes the stream, and emits the `done` event synchronously.
   *
   * If this controller has delayed events pending, delays the done event, too.
   * This ensures that events are sent in order.
   *
   * If this controller has multiple listeners, and is already emitting events
   * synchronously, delays sending the done event. This ensures that all
   * listeners receive the events in order.
   */
  Future closeSync();

  // Note that cancelOnError is now false by default.
  // Also, `addStream` is now allowed to be interleaved with other `add` functions.
  Future addStream(Stream<T> source, {bool cancelOnError: false});
}
```

We would prefer if `add` just took a named argument `sync: true`, instead of having two different methods, but this wouldn't work with `addError` which already takes a positional optional argument (the stack trace). Currently, the Dart language doesn't allow positional and named optional arguments in the same function. (We looked at this, but aren't sure yet, how we could implement it efficiently in DDC).

A few more comments on StreamController (that will eventually make it into the dartdocs):
* `add` always puts the event into an internal queue and emits it at a later microtask. If another event was already queued, they can be emitted together.
* `addSync` emits the event synchronously unless the queue is not empty. This guarantees that the events are emitted in order. We could also emit synchronously, but we believe that the guarantee of order is more important. Many listeners already are asynchronous anyway (for example with an `async` keyword), and a synchronous push of the event wouldn't guarantee a synchronous treatment of the value.
* `addSync` while another event is already doing an `addSync` stores the event in the queue (as if add was called). This only happens when one of the listeners adds another event. This measure is also necessary to ensure that events are emitted in order (when there is more than one listener).

The absence of `completeErrorSync` in the `Completer` interface is on purpose: emitting errors synchronously can be a painful source of errors. This is less of an issue for streams, because they only emit events when they have listeners. For futures, developers should register error handlers as soon as possible, since the errors would otherwise be reported as uncaught. With streams, the event processing only starts when the user starts listening.

As can be seen in this snippet, the fundamental changes to `Completer` and `StreamController` are their ability to emit both synchronously and asynchronously from the same instance.

A few more minor changes are also visible (all marked with a comment):
- The `onCancel` function parameter (to the `StreamController` constructor) is now marked to return `FutureOr<void>`. It was `dynamic` before. In practice we recommended to implement this return-type already before.
- all `sync` constructor named arguments are gone. An alternative to providing `add` and `addSync` would be to keep these arguments. It would make the controller less powerful, and we like that users now have to think at every event whether they really want to push the value synchronously.
- the `addStreams` default value for `cancelOnError` is now false. If the added streams has errors, we should just forward them. If the listeners can deal with errors, then they want to see the errors. If they don't then they will cancel anyway (giving the same behavior as if the `cancelOnError` was true).
- `addStream` calls are allowed to be interleaved with other add calls. Removing this restriction makes the implementation of the controller simpler and gives the user more flexibility. 

We also removed the `Completer.sync` constructor (since it's now covered by the normal `Completer` class).

> This change sounds more scary (from a migration point-of-view) than it is: we allow *more*, not less. This means that programs continue working. Over time, code that relies on the guarantees that Dart 1.x gave will have to adapt to work without these guarantees.
>
> The removal of `sync` from the constructors is easy to fix by providing a class that simulates the old behavior, wrapping the `StreamController` or `Completer` and just calling the `xSync` versions.
>
> That said: there are small and subtle changes that do affect the behavior of Streams. This change should be done as soon as possible to have enough time to migrate existing code, in case we encounter unexpected difficulties.

### Removal of Different Stream Types
So far, a `Stream` was either *broadcast* or *single-subscription streams*. Broadcast streams were allowed to have multiple listeners, and were known to potentially lose events. That is, a listener could join at a later moment, and not receive all the events. Similarly, for some broadcast streams (like in the HTML library), pausing the stream was equivalent to deregistering from the stream entirely.

Things got a bit more interesting, once streams were transformed. For single-subscription streams, the semantics and restrictions are clear: a transformed single-subscription stream is again a single-subscription stream:

![single-subscription](single_subscription.svg)

For broadcast streams, a guideline (and often guarantee) was that the transformation of a broadcast stream was again a broadcast stream. This made it possible to allow multiple listeners for the transformed stream as well:

![broadcast](broadcast.svg)

However, this shouldn't be necessary: all transformations could just forward their listen-requests. That is, when a transformed stream is listened to, the transformer should just ask the next stream for a stream-subscription and transform the events this way.
This means that a transformed broadcast stream could still accept multiple listeners, even if the resulting stream was not a broadcast stream.

![transformed broadcast](broadcast_transformer.svg)

In practice this was actually already implemented for all basic transformations like `map`, `where`, ... With Dart 2.0 we will make this more automatic: every `transform` call on a stream will `bind` to the next stream for every request. This means, that transformers don't need to worry about single-subscription or broadcast streams anymore. If the listen requests eventually reach an event source that can handle multiple listeners, then the connection is successful.

In this scenario, `asBroadcastStream` gets a new meaning: it avoids multiple instantiations of the transformers:

![transformed broadcast](as_broadcast.svg)

This allows us to drop the distinction between single-subscription streams and broadcast streams. The decision on how many subscribers are supported is now the full responsibility of the event source. We will, of course, continue to provide the broadcast and single-subscription `StreamController`s. However, it's now also trivial to support other variants, like a *multi-subscription stream* that supports multiple listeners, but where each of them is treated individually.

We are considering adding the following constructor for this purpose:

``` dart
  /**
   * Creates a stream where each individual listener has a fresh controller.
   *
   * Whenever the stream is listened to, the provided [onListen] function is
   * invoked with a fresh [StreamController]. The closure should then set
   * [StreamController.onPause], [StreamController.onResume] and
   * [StreamController.onCancel], and start emitting values through the controller.
   */
  factory Stream.multicast(void onListen(StreamController controller)) { ... }
*/
```

Whenever this stream is listened to, the callback is invoked with a *fresh* single-subscription StreamController which is then responsible for handling the listener. In combination with transformers that bind for every listener, this makes it possible to listen to (some) streams (and their transformations) multiple times. For example, a new File("foo.txt") may be implemented as a multicast stream, where each listener just opens the file again.

![multicast](multicast.svg)

Since transformers don't need to know anymore whether the incoming stream is a broadcast stream or not, we have removed the `isBroadcast` property from `Stream`. There is no practical use for it anymore. (Users better know whether they can listen multiple times to a stream. There is no benefit in asking the stream).

However, the `asBroadcastStream` now becomes even more important: it makes sure that listeners actually listen to the same instance of a multicast stream. Every listener to the `asBroadcastStream` will receive the same events (when subscribed at the same time).

> Removing the `isBroadcast` member requires to rewrite existing code. However, the new behavior and concepts should make the affected code just simpler. The new `Stream.multicast` constructor would make many transitions straight-forward.
>
> The `transform` behavior (calling `bind` for every listener) only affects broadcast streams with more than one listener.
>
> The other changes are non-breaking in that they allow code to run that was previously (dynamically) rejected.
>
> We expect few breakages, but intend to do this change as soon as possible, in case we encounter unexpected difficulties.

### Functionality and Cleanups
As mentioned in the previous section, `Stream` lose the `isBroadcast` property, and likely gain a new constructor (`Stream.multicast`). Here are the additional changes to the class:

#### Cleanups / Consistency
- `toList` now takes a `growable` named argument to be consistent with `Iterable.toList`: `Future<List<T>> toList({bool growable: true})`.
- `firstWhere` and `lastWhere` require the `orElse` clause to provide a `T`. This makes it consistent with `Iterable` and makes it possible to type the returned `Future`:
  ``` dart
   `Future<T> firstWhere(bool test(T element), {FutureOr<T> orElse()})`.
  ```
- `singleWhere` now takes an `orElse` similar to `firstWhere` and `lastWhere`:
  ``` dart
  Future<T> singleWhere(bool test(T element), {FutureOr<T> orElse()}).
  ```

The `StreamSubscription` is updated to use setters to modify handlers. In Dart 1.x `onData`, `onError` and `onDone` were functions that users could invoke to set new handlers. In Dart 2.x these are going to be setters. This makes it consistent with the corresponding `onListen`, `onPause`, `onResume` and `onCancel` handlers on `StreamController`.

The `StreamTransformer` gets a `cast` method similar to collections and Converter. Since `StreamTransformer` is generic and Dart generics are covariant, it is possible to run into cases where a transformer is perfectly able to do its work, but the type system gets in the way.

For example, a `StreamTransformer<Iterable<String>, String>` is not a valid argument to `Stream<List<String>>.transform`, even though it would be able to handle all the lists. The `cast` on `StreamTransformer`, like other `cast` methods, allows the user to change the static type to something compatible.

> In theory, the changes to `firstWhere` and `lastWhere` could break some code. In practice, we don't expect this change to affect any user.
>
> The other changes to the signatures only add optional arguments and thus only affect subtypes of `Stream`. This also applies to the `StreamTransformer` change.
>
> The `StreamSubscription` update looks scary, but the migration can be done in a nice controlled manner. We can provide getters and setters for the functions in parallel, so that both variants are valid for some time. Once the migration is complete we can remove the getter versions.

#### Removed
`isBroadcast` (see above)

> The removal of `isBroadcast` is discussed above.

#### RX (Reactive Extensions) functionality
The following methods were inspired by RX.

``` dart
 /**
   * Merges the provided [sources].
   */
  static Stream<T> merge<T>(Iterable<Stream<T>> sources);

  /**
   * Listens to all [sources] in parallel and emits a list of the individual
   * values when each source has emitted a new value.
   */
  static Stream<List<T>> zip<T>(Iterable<Stream<T>> sources);

 /**
   * Groups the elements of this stream according to the [key] function.
   */
  Future<Map<K, List<T>>> groupBy<K>(K key(T element));
 
 /**
   * Groups the elements of this stream according to the [key] function.
   *
   * As soon as the [key] function returns a key that hasn't been seen before,
   * the returned stream emits a new [EventGroup] for that key. 
   * The [EventGroup.events] stream then that event, and all further events
   * with an equivalent key.
   */
  Stream<EventGroup<K, E>> group<K>(K key(T element));

  /**
   * Combines a sequence of values by repeatedly applying [combine] and emits
   * every intermediate result.
   *
   * Similar to [Stream.fold], except that every intermediate result is
   * emitted on the returned stream.
   *
   * If [emitInitialValue] is `true` also emits the [initialValue] as soon
   * as the stream is listened to.
   */
  Stream<S> foldEmit<S>(S initialValue, S combine(S previous, T element),
      { bool emitInitialValue: false });

  /**
   * Combines a sequence of values by repeatedly applying [combine] and emits
   * every intermediate result.
   *
   * Similar to [Stream.reduce], but emits every intermediate result.
   */
  Stream<T> reduceEmit(T combine(T previous, T element));

  /**
   * Concatenates this stream with [other].
   */
  Stream<T> followedBy(Stream<T> other);

  /**
   * Drops any data event that happens shortly after another undropped event.
   *
   * Returns a new stream that emits the same data events as the this stream,
   * except that all events that happens within [interval] of a
   * previously emitted event is dropped.
   *
   * Error and done events are always forwarded to the returned stream.
   *
   * The returned stream is a broadcast stream if this stream is.
   *
   * Since `throttle` may drop some events, it should only be used on streams
   * where each event can be interpreted individually. Such streams are
   * typically broadcast streams.
   *
   * Effectively, each emitted data event starts a timer, and until that timer
   * reaches [duration], all further events are dropped.
   * This differs from [debounce] which restarts the timer
   * after dropped events too.
   */
  Stream<T> throttle(Duration interval);

  /**
   * Drops any data event that happens shortly after another incoming event.
   *
   * Returns a new stream that emits the same data events as the this stream,
   * except that all events that happens within [interval] of a
   * previously received event is dropped.
   *
   * Error and done events are always forwarded to the returned stream.
   *
   * The returned stream is a broadcast stream if this stream is.
   *
   * Since `debounce` may drop some events, it should only be used on streams
   * where each event can be interpreted individually. Such streams are
   * typically broadcast streams.
   *
   * Effectively, each received data event starts a timer, and until that timer
   * reaches [duration], any new event is dropped and the timer is restarted.
   * This differs from [throttle] which doesn't restarts the timer
   * after dropped events.
   */
  Stream<T> debounce(Duration interval);

  /**
   * Returns a multicast stream that replays all events of this stream.
   *
   * Each listener of the resulting stream receives all events of this stream.
   * This means that all events must be buffered. Users need to pay attention
   * not to leak memory this way.
   *
   * If no [bufferSize] is provided (or it is `null`) then the
   * returned stream is able to replay *all* previously emitted events.
   *
   * If [bufferSize] is provided, then only the most recent [bufferSize]
   * events are stored and replayed.
   */
  Stream<T> replay({int bufferSize});
```

> All of these methods only affect subtypes of `Stream`.

### Convenience
For convenience and consistency with dart:core, we have added `whereNot` to `Stream`.

``` dart
  /**
   * Creates a new stream from this stream that discards some elements.
   *
   * Same as:
   *
   * ```
   * where((event) => !test(event))
   * ```
   */
  Stream<T> whereNot(bool test(T event)) {
    return new WhereStream(this, test, invert: true);
  }
```

> This method only affects subtypes of `Stream`.

### Timer and Cleanups
The original `Timer` implementation ensured that all ticks of a periodic timer would execute. If the timer fell behind, it would try to catch up, but would never lose ticks. This behavior leads to big problems when a computer goes to sleep (or a Dart program isn't executed for a long time). When the Dart program is resumed, it will try to run *all* missed ticks. In Dart 2.x, it will skip the missed ticks. In return, the `Timer` class has a `tick` member that informs the program how many ticks should have passed:

``` dart
  /**
   * The number of durations preceding the most recent timer event.
   *
   * The value starts at zero and is incremented each time a timer event
   * occurs, so each callback will see a larger value than the previous one.
   *
   * If a periodic timer with a non-zero duration is delayed too much,
   * so more than one tick should have happened,
   * all but the last tick in the past are considered "missed",
   * and no callback is invoked for them.
   * The [tick] count reflects the number of durations that have passed and
   * not the number of callback invocations that have happened.
   */
  int get tick;
```

Since we already modified the `Timer` class, we also added the missing `isPeriodic` member.

As a cleanup we moved the `StreamView` class to the `async` package, and removed the `DeferredLibrary` class (which was marked for removal with Dart 1.8).

> This change only affects subtypes of `Timer`.
> The behavioral change of timers is, in theory, breaking, but only affects VM users (since we still use the JS timers in browser). We expect that most programs are behaving better with this change.

## dart:collection
We cleaned up the `dart:collection` library. A lot of classes in this library are now in `package:collection`. For most users, this just means that they have to add an `import "package:collection/collection.dart";` to their files.

#### Moved
The following classes are moved to `package:collection`:
- `UnmodifiableListView`
- `HasNextIterator`
- `LinkedList` and `LinkedListEntry`
- `UnmodifiableMapBase`
- `MapView` and `UnmodifiableMapView`
- `DoubleLinkedQueue` and `DoubleLinkedQueueEntry`
- `SplayTreeMap` and `SplayTreeSet`

#### Cleanups
The `LinkedHashMap` doesn't implement the `HashMap` interface anymore. These are two distinct classes and just happened to have the same suffix. The `{}` literal still creates a `LinkedHashMap`.

`Maps` has been removed. The `Maps.mapToString` has been moved to `MapBase` (similar to `listToString` which is on `ListBase`).

The `Queue` class got its `add` method removed, since it was just a synonym for `addLast`. Since the `addLast` method starts with the same prefix, users should have no difficulties finding it (with code completion). We renamed `addAll` to `addAllLast` and added `addAllFirst`.

We added `copy` and `castCopy`, similar to `List`, `Set` and `Map`.

``` dart
Queue<E> copy([int start = 0, int end]);
Queue<T> castCopy<T>([int start = 0, int end]);
```

The `ListQueue` now implements both the `Queue` and `List` interface.

> We expect the `LinkedHashMap` interface-change to cause no breakage.
>
> The `Maps` class should have never been exposed. The `mapToString` method is the most used one, and will continue to be available in the `MapBase` class. The migration thus only needs to point from one static function to another.
>
> The `Queue` class is relatively rarely used, and the change from `add` (resp. `addAll`) to `addLast` (resp. `addAllLast`) is straightforward. We are still debating whether the change is worth the pain it causes, though. Please provide feedback.
>
> Making `ListQueue` implement `List` requires the class to have more methods. We will need to pay attention not to increase the output size of dart2js. This should be achievable by reusing as many `ListMixin` methods as possible.

#### Strong Typing
Similar to other collection classes, the `from` constructor of `Queue` and `ListQueue` now take typed iterables:
``` dart
factory Queue.from(Iterable<E> elements);  // Now requires a typed Iterable.
factory ListQueue.from(Iterable<E> elements);  // Now requires a typed Iterable.
```

We found very few uses of `Queue.from`. Among the ones that exist, many already satisfy the new contract and won't break with this change.

## dart:convert
In the `dart:convert` library, we will do the following changes:
1. the `Base64Decoder` now ignores new lines. This makes the converter easier to use and the change has almost no drawbacks.
2. a new `Encoding.register` method allows to add new encodings to the database: `static void register(String name, Encoding encoding)`.
  The Encoding map was always designed to be user-extensible, and this method is the first step in that direction.
3. the `JsonCodec.withReviver` constructor is removed. The unnamed constructor provides the same functionality.
4. Added `cast` method to Converter. See the `StreamTransformer.cast` explanation earlier for why this is necessary.

> Only the `JsonCodec.withReviver` change is breaking, and can be easily fixed by using the unnamed constructor.
> The extra method on `Converter` should be inherited by all classes extending `Converter`. We already recommend that all converters do so.

## dart:isolate
We updated the `spawn` function to be generic. This could (should) have happened during the transition to strong mode:
``` dart
static Future<Isolate> spawn<T>(void entryPoint(T message), T message, ...)
```

We also fixed a major usability issue with `Isolate.errors`. The `errors` stream can be used to listen to errors of isolates (other isolates or the current, own, isolate). In Dart 1.x errors were reported as errors, which meant that users had to provide an *error*-handler and not a simple data handler. When users didn't provide an error handler, it could bring down the current isolate. Even worse, in the browser, this could lead to unresponsive browsers, when the stream was listening to errors from the same isolate. If the user didn't provide an error-handler, the error would reach the uncaught-error-handler and be reemitted in the `errors` stream leading to an infinite loop.

In the future, the `errors` stream will thus return a `Stream<AsyncError>` which only requires a data handler. For convenience, we also refactored the stream to send a `done` event when the isolate closes.

> The `spawn` change is most likely non-breaking, or revealing bugs in the program.
>
> The `errors` change is breaking, but we can make the transition easier by preserving  (for some time) the old behavior when the user only provides error-handlers to the `Stream.listen` function.

## dart:math
We trimmed `dart:math`. It now serves its intended purpose of providing mathematical functionality.

We moved `Point` and `Rectangle` to `dart:html`. This means that non-browser users will have to use a package (or write their own class as Flutter did). We are still investigating whether this is just a theoretical issue, or whether this move would lead to serious breakages. (Please submit feedback).

`min` and `max` were moved to `num`, `int` and `double` with non-generic signatures for `int` and `double`.

The `Random` class was moved to `dart:core`. It is used relatively frequently and has little potential of conflicting with user-defined classes.

Without these classes, the `dart:math` library consists entirely of mathematical constants and functions like `pi`, `sin`, or `pow`. We want to add more functionality in the future, but this is not planned in the near future.

> Most classes and functions have only been moved to different places.
>
> For non-browsers, users might need to fall back to a package to use Point and Rectangle.

## dart:typed_data
The typed_data library now contains the `BytesBuilder` class which was previously part of `dart:io`. It is still exposed through `dart:io`, but lives in `typed_data` now. This means that the class can be used in browser environments, too.

The `ByteBuffer` class now has a `copy` method that makes it possible to get a copy of a given range:
``` dart
  /**
   * Returns a copy of the buffer or a part of the buffer.
   */
  ByteBuffer copy([int start = 0, int end]);
```

Since Dart 2.0 will switch to fixed-size integers, we will also add a `BigInt` class to the core libraries. We initially planned to add the class in the `typed_data` library (which is why we mention it here), but have already heard feedback that `dart:core` might be a better place.

Developers targeting dart2js can use this class as well. The `BigInt` class is *not* implementing `num`, and is completely independent of the `num` hierarchy.

There is a first draft of the class in the Gerrit CL for this document (see the introduction).

Finally, we renamed the `Endianness` class and its constants. The class is now called `Endian` and the contained constants have been renamed from `LITTLE_ENDIAN`, `BIG_ENDIAN` and `HOST_ENDIAN` to simply `little`, `big` and `host`.

> Non breaking except for the constants changes (which exist in every library), and for subtypes of `ByteBuffer`.
