diff --git a/CHANGELOG.md b/CHANGELOG.md
index 23a3e2a..8f44d60 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,9 +2,6 @@
 
 ### Core library changes
 
-* `dart:core`
-  * Improved performance when parsing some common URIs.
-  * Fixed bug in `Uri.resolve` (SDK issue [26804](https://github.com/dart-lang/sdk/issues/26804)).
 * `dart:io`
   * Adds file locking modes `FileLock.BLOCKING_SHARED` and
     `FileLock.BLOCKING_EXCLUSIVE`.
diff --git a/pkg/analyzer/lib/src/util/fast_uri.dart b/pkg/analyzer/lib/src/util/fast_uri.dart
index 0df5ce05..8af548c 100644
--- a/pkg/analyzer/lib/src/util/fast_uri.dart
+++ b/pkg/analyzer/lib/src/util/fast_uri.dart
@@ -62,7 +62,23 @@
   bool get hasFragment => false;
 
   @override
-  int get hashCode => _text.hashCode;
+  int get hashCode {
+    // This code is copied from the standard Uri implementation.
+    // It is important that Uri and FastUri generate compatible hashCodes
+    // because Uri and FastUri may be used as keys in the same map.
+    int combine(part, current) {
+      // The sum is truncated to 30 bits to make sure it fits into a Smi.
+      return (current * 31 + part.hashCode) & 0x3FFFFFFF;
+    }
+    return _hashCode ??= combine(
+        scheme,
+        combine(
+            userInfo,
+            combine(
+                host,
+                combine(port,
+                    combine(path, combine(query, combine(fragment, 1)))))));
+  }
 
   @override
   bool get hasPort => false;
diff --git a/runtime/lib/uri_patch.dart b/runtime/lib/uri_patch.dart
index 80024c2..2664b9b 100644
--- a/runtime/lib/uri_patch.dart
+++ b/runtime/lib/uri_patch.dart
@@ -16,16 +16,14 @@
 _UriBaseClosure _uriBaseClosure = _unsupportedUriBase;
 
 patch class Uri {
-  /* patch */ static Uri get base => _uriBaseClosure();
-}
-
-patch class _Uri {
   static final bool _isWindowsCached = _isWindowsPlatform;
 
-  static bool get _isWindowsPlatform native "Uri_isWindowsPlatform";
-
   /* patch */ static bool get _isWindows => _isWindowsCached;
 
+  /* patch */ static Uri get base => _uriBaseClosure();
+
+  static bool get _isWindowsPlatform native "Uri_isWindowsPlatform";
+
   /* patch */ static String _uriEncode(List<int> canonicalTable,
                                        String text,
                                        Encoding encoding,
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 129ce01..9004574 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -587,17 +587,15 @@
 @patch
 class Uri {
   @patch
+  static bool get _isWindows => false;
+
+  @patch
   static Uri get base {
     String uri = Primitives.currentUri();
     if (uri != null) return Uri.parse(uri);
     throw new UnsupportedError("'Uri.base' is not supported");
   }
-}
 
-@patch
-class _Uri {
-  @patch
-  static bool get _isWindows => false;
 
   // Matches a String that _uriEncodes to itself regardless of the kind of
   // component.  This corresponds to [_unreservedTable], i.e. characters that
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index b43b3ad..5718ca8 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -4,24 +4,6 @@
 
 part of dart.core;
 
-// Frequently used character codes.
-const int _SPACE = 0x20;
-const int _PERCENT = 0x25;
-const int _PLUS = 0x2B;
-const int _DOT = 0x2E;
-const int _SLASH = 0x2F;
-const int _COLON = 0x3A;
-const int _UPPER_CASE_A = 0x41;
-const int _UPPER_CASE_Z = 0x5A;
-const int _LEFT_BRACKET = 0x5B;
-const int _BACKSLASH = 0x5C;
-const int _RIGHT_BRACKET = 0x5D;
-const int _LOWER_CASE_A = 0x61;
-const int _LOWER_CASE_F = 0x66;
-const int _LOWER_CASE_Z = 0x7A;
-
-const String _hexDigits = "0123456789ABCDEF";
-
 /**
  * A parsed URI, such as a URL.
  *
@@ -33,17 +15,77 @@
  * [uris]: https://www.dartlang.org/docs/dart-up-and-running/ch03.html#uris
  * [libtour]: https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html
  */
-abstract class Uri {
+class Uri {
   /**
-   * Returns the natural base URI for the current platform.
+   * The scheme component of the URI.
    *
-   * When running in a browser this is the current URL of the current page
-   * (from `window.location.href`).
+   * Returns the empty string if there is no scheme component.
    *
-   * When not running in a browser this is the file URI referencing
-   * the current working directory.
+   * A URI scheme is case insensitive.
+   * The returned scheme is canonicalized to lowercase letters.
    */
-  external static Uri get base;
+  // We represent the missing scheme as an empty string.
+  // A valid scheme cannot be empty.
+  final String scheme;
+
+  /**
+   * The user-info part of the authority.
+   *
+   * Does not distinguish between an empty user-info and an absent one.
+   * The value is always non-null.
+   * Is considered absent if [_host] is `null`.
+   */
+  final String _userInfo;
+
+  /**
+   * The host name of the URI.
+   *
+   * Set to `null` if there is no authority in the URI.
+   * The host name is the only mandatory part of an authority, so we use
+   * it to mark whether an authority part was present or not.
+   */
+  final String _host;
+
+  /**
+   * The port number part of the authority.
+   *
+   * The port. Set to null if there is no port. Normalized to null if
+   * the port is the default port for the scheme.
+   */
+  int _port;
+
+  /**
+   * The path of the URI.
+   *
+   * Always non-null.
+   */
+  String _path;
+
+  // The query content, or null if there is no query.
+  final String _query;
+
+  // The fragment content, or null if there is no fragment.
+  final String _fragment;
+
+  /**
+   * Cache the computed return value of [pathSegements].
+   */
+  List<String> _pathSegments;
+
+  /**
+   * Cache the computed return value of [queryParameters].
+   */
+  Map<String, String> _queryParameters;
+  Map<String, List<String>> _queryParameterLists;
+
+  /// Internal non-verifying constructor. Only call with validated arguments.
+  Uri._internal(this.scheme,
+                this._userInfo,
+                this._host,
+                this._port,
+                this._path,
+                this._query,
+                this._fragment);
 
   /**
    * Creates a new URI from its components.
@@ -116,15 +158,39 @@
    * general delimiters, are escaped if necessary.
    * If `fragment` is omitted or `null`, the URI has no fragment part.
    */
-  factory Uri({String scheme,
-               String userInfo,
+  factory Uri({String scheme : "",
+               String userInfo : "",
                String host,
                int port,
                String path,
                Iterable<String> pathSegments,
                String query,
                Map<String, dynamic/*String|Iterable<String>*/> queryParameters,
-               String fragment}) = _Uri;
+               String fragment}) {
+    scheme = _makeScheme(scheme, 0, _stringOrNullLength(scheme));
+    userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo));
+    host = _makeHost(host, 0, _stringOrNullLength(host), false);
+    // Special case this constructor for backwards compatibility.
+    if (query == "") query = null;
+    query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters);
+    fragment = _makeFragment(fragment, 0, _stringOrNullLength(fragment));
+    port = _makePort(port, scheme);
+    bool isFile = (scheme == "file");
+    if (host == null &&
+        (userInfo.isNotEmpty || port != null || isFile)) {
+      host = "";
+    }
+    bool hasAuthority = (host != null);
+    path = _makePath(path, 0, _stringOrNullLength(path), pathSegments,
+                     scheme, hasAuthority);
+    if (scheme.isEmpty && host == null && !path.startsWith('/')) {
+      path = _normalizeRelativePath(path);
+    } else {
+      path = _removeDotSegments(path);
+    }
+    return new Uri._internal(scheme, userInfo, host, port,
+                             path, query, fragment);
+  }
 
   /**
    * Creates a new `http` URI from authority, path and query.
@@ -161,7 +227,9 @@
    */
   factory Uri.http(String authority,
                    String unencodedPath,
-                   [Map<String, String> queryParameters]) = _Uri.http;
+                   [Map<String, String> queryParameters]) {
+    return _makeHttpUri("http", authority, unencodedPath, queryParameters);
+  }
 
   /**
    * Creates a new `https` URI from authority, path and query.
@@ -171,7 +239,424 @@
    */
   factory Uri.https(String authority,
                     String unencodedPath,
-                    [Map<String, String> queryParameters]) = _Uri.https;
+                    [Map<String, String> queryParameters]) {
+    return _makeHttpUri("https", authority, unencodedPath, queryParameters);
+  }
+
+  /**
+   * Returns the authority component.
+   *
+   * The authority is formatted from the [userInfo], [host] and [port]
+   * parts.
+   *
+   * Returns the empty string if there is no authority component.
+   */
+  String get authority {
+    if (!hasAuthority) return "";
+    var sb = new StringBuffer();
+    _writeAuthority(sb);
+    return sb.toString();
+  }
+
+  /**
+   * Returns the user info part of the authority component.
+   *
+   * Returns the empty string if there is no user info in the
+   * authority component.
+   */
+  String get userInfo => _userInfo;
+
+  /**
+   * Returns the host part of the authority component.
+   *
+   * Returns the empty string if there is no authority component and
+   * hence no host.
+   *
+   * If the host is an IP version 6 address, the surrounding `[` and `]` is
+   * removed.
+   *
+   * The host string is case-insensitive.
+   * The returned host name is canonicalized to lower-case
+   * with upper-case percent-escapes.
+   */
+  String get host {
+    if (_host == null) return "";
+    if (_host.startsWith('[')) {
+      return _host.substring(1, _host.length - 1);
+    }
+    return _host;
+  }
+
+  /**
+   * Returns the port part of the authority component.
+   *
+   * Returns the defualt port if there is no port number in the authority
+   * component. That's 80 for http, 443 for https, and 0 for everything else.
+   */
+  int get port {
+    if (_port == null) return _defaultPort(scheme);
+    return _port;
+  }
+
+  // The default port for the scheme of this Uri..
+  static int _defaultPort(String scheme) {
+    if (scheme == "http") return 80;
+    if (scheme == "https") return 443;
+    return 0;
+  }
+
+  /**
+   * Returns the path component.
+   *
+   * The returned path is encoded. To get direct access to the decoded
+   * path use [pathSegments].
+   *
+   * Returns the empty string if there is no path component.
+   */
+  String get path => _path;
+
+  /**
+   * Returns the query component. The returned query is encoded. To get
+   * direct access to the decoded query use [queryParameters].
+   *
+   * Returns the empty string if there is no query component.
+   */
+  String get query => (_query == null) ? "" : _query;
+
+  /**
+   * Returns the fragment identifier component.
+   *
+   * Returns the empty string if there is no fragment identifier
+   * component.
+   */
+  String get fragment => (_fragment == null) ? "" : _fragment;
+
+  /**
+   * Creates a new `Uri` object by parsing a URI string.
+   *
+   * If [start] and [end] are provided, only the substring from `start`
+   * to `end` is parsed as a URI.
+   *
+   * If the string is not valid as a URI or URI reference,
+   * a [FormatException] is thrown.
+   */
+  static Uri parse(String uri, [int start = 0, int end]) {
+    // This parsing will not validate percent-encoding, IPv6, etc.
+    // When done splitting into parts, it will call, e.g., [_makeFragment]
+    // to do the final parsing.
+    //
+    // Important parts of the RFC 3986 used here:
+    // URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+    //
+    // hier-part     = "//" authority path-abempty
+    //               / path-absolute
+    //               / path-rootless
+    //               / path-empty
+    //
+    // URI-reference = URI / relative-ref
+    //
+    // absolute-URI  = scheme ":" hier-part [ "?" query ]
+    //
+    // relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
+    //
+    // relative-part = "//" authority path-abempty
+    //               / path-absolute
+    //               / path-noscheme
+    //               / path-empty
+    //
+    // scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+    //
+    // authority     = [ userinfo "@" ] host [ ":" port ]
+    // userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
+    // host          = IP-literal / IPv4address / reg-name
+    // port          = *DIGIT
+    // reg-name      = *( unreserved / pct-encoded / sub-delims )
+    //
+    // path          = path-abempty    ; begins with "/" or is empty
+    //               / path-absolute   ; begins with "/" but not "//"
+    //               / path-noscheme   ; begins with a non-colon segment
+    //               / path-rootless   ; begins with a segment
+    //               / path-empty      ; zero characters
+    //
+    // path-abempty  = *( "/" segment )
+    // path-absolute = "/" [ segment-nz *( "/" segment ) ]
+    // path-noscheme = segment-nz-nc *( "/" segment )
+    // path-rootless = segment-nz *( "/" segment )
+    // path-empty    = 0<pchar>
+    //
+    // segment       = *pchar
+    // segment-nz    = 1*pchar
+    // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
+    //               ; non-zero-length segment without any colon ":"
+    //
+    // pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
+    //
+    // query         = *( pchar / "/" / "?" )
+    //
+    // fragment      = *( pchar / "/" / "?" )
+    const int EOI = -1;
+
+    String scheme = "";
+    String userinfo = "";
+    String host = null;
+    int port = null;
+    String path = null;
+    String query = null;
+    String fragment = null;
+    if (end == null) end = uri.length;
+
+    int index = start;
+    int pathStart = start;
+    // End of input-marker.
+    int char = EOI;
+
+    void parseAuth() {
+      if (index == end) {
+        char = EOI;
+        return;
+      }
+      int authStart = index;
+      int lastColon = -1;
+      int lastAt = -1;
+      char = uri.codeUnitAt(index);
+      while (index < end) {
+        char = uri.codeUnitAt(index);
+        if (char == _SLASH || char == _QUESTION || char == _NUMBER_SIGN) {
+          break;
+        }
+        if (char == _AT_SIGN) {
+          lastAt = index;
+          lastColon = -1;
+        } else if (char == _COLON) {
+          lastColon = index;
+        } else if (char == _LEFT_BRACKET) {
+          lastColon = -1;
+          int endBracket = uri.indexOf(']', index + 1);
+          if (endBracket == -1) {
+            index = end;
+            char = EOI;
+            break;
+          } else {
+            index = endBracket;
+          }
+        }
+        index++;
+        char = EOI;
+      }
+      int hostStart = authStart;
+      int hostEnd = index;
+      if (lastAt >= 0) {
+        userinfo = _makeUserInfo(uri, authStart, lastAt);
+        hostStart = lastAt + 1;
+      }
+      if (lastColon >= 0) {
+        int portNumber;
+        if (lastColon + 1 < index) {
+          portNumber = 0;
+          for (int i = lastColon + 1; i < index; i++) {
+            int digit = uri.codeUnitAt(i);
+            if (_ZERO > digit || _NINE < digit) {
+              _fail(uri, i, "Invalid port number");
+            }
+            portNumber = portNumber * 10 + (digit - _ZERO);
+          }
+        }
+        port = _makePort(portNumber, scheme);
+        hostEnd = lastColon;
+      }
+      host = _makeHost(uri, hostStart, hostEnd, true);
+      if (index < end) {
+        char = uri.codeUnitAt(index);
+      }
+    }
+
+    // When reaching path parsing, the current character is known to not
+    // be part of the path.
+    const int NOT_IN_PATH = 0;
+    // When reaching path parsing, the current character is part
+    // of the a non-empty path.
+    const int IN_PATH = 1;
+    // When reaching authority parsing, authority is possible.
+    // This is only true at start or right after scheme.
+    const int ALLOW_AUTH = 2;
+
+    // Current state.
+    // Initialized to the default value that is used when exiting the
+    // scheme loop by reaching the end of input.
+    // All other breaks set their own state.
+    int state = NOT_IN_PATH;
+    int i = index;  // Temporary alias for index to avoid bug 19550 in dart2js.
+    while (i < end) {
+      char = uri.codeUnitAt(i);
+      if (char == _QUESTION || char == _NUMBER_SIGN) {
+        state = NOT_IN_PATH;
+        break;
+      }
+      if (char == _SLASH) {
+        state = (i == start) ? ALLOW_AUTH : IN_PATH;
+        break;
+      }
+      if (char == _COLON) {
+        if (i == start) _fail(uri, start, "Invalid empty scheme");
+        scheme = _makeScheme(uri, start, i);
+        i++;
+        if (scheme == "data") {
+          // This generates a URI that is (potentially) not path normalized.
+          // Applying part normalization to a non-hierarchial URI isn't
+          // meaningful.
+          return UriData._parse(uri, i, null).uri;
+        }
+        pathStart = i;
+        if (i == end) {
+          char = EOI;
+          state = NOT_IN_PATH;
+        } else {
+          char = uri.codeUnitAt(i);
+          if (char == _QUESTION || char == _NUMBER_SIGN) {
+            state = NOT_IN_PATH;
+          } else if (char == _SLASH) {
+            state = ALLOW_AUTH;
+          } else {
+            state = IN_PATH;
+          }
+        }
+        break;
+      }
+      i++;
+      char = EOI;
+    }
+    index = i;  // Remove alias when bug is fixed.
+
+    if (state == ALLOW_AUTH) {
+      assert(char == _SLASH);
+      // Have seen one slash either at start or right after scheme.
+      // If two slashes, it's an authority, otherwise it's just the path.
+      index++;
+      if (index == end) {
+        char = EOI;
+        state = NOT_IN_PATH;
+      } else {
+        char = uri.codeUnitAt(index);
+        if (char == _SLASH) {
+          index++;
+          parseAuth();
+          pathStart = index;
+        }
+        if (char == _QUESTION || char == _NUMBER_SIGN || char == EOI) {
+          state = NOT_IN_PATH;
+        } else {
+          state = IN_PATH;
+        }
+      }
+    }
+
+    assert(state == IN_PATH || state == NOT_IN_PATH);
+    if (state == IN_PATH) {
+      // Characters from pathStart to index (inclusive) are known
+      // to be part of the path.
+      while (++index < end) {
+        char = uri.codeUnitAt(index);
+        if (char == _QUESTION || char == _NUMBER_SIGN) {
+          break;
+        }
+        char = EOI;
+      }
+      state = NOT_IN_PATH;
+    }
+
+    assert(state == NOT_IN_PATH);
+    bool hasAuthority = (host != null);
+    path = _makePath(uri, pathStart, index, null, scheme, hasAuthority);
+
+    if (char == _QUESTION) {
+      int numberSignIndex = -1;
+      for (int i = index + 1; i < end; i++) {
+        if (uri.codeUnitAt(i) == _NUMBER_SIGN) {
+          numberSignIndex = i;
+          break;
+        }
+      }
+      if (numberSignIndex < 0) {
+        query = _makeQuery(uri, index + 1, end, null);
+      } else {
+        query = _makeQuery(uri, index + 1, numberSignIndex, null);
+        fragment = _makeFragment(uri, numberSignIndex + 1, end);
+      }
+    } else if (char == _NUMBER_SIGN) {
+      fragment = _makeFragment(uri, index + 1, end);
+    }
+    return new Uri._internal(scheme,
+                             userinfo,
+                             host,
+                             port,
+                             path,
+                             query,
+                             fragment);
+  }
+
+  // Report a parse failure.
+  static void _fail(String uri, int index, String message) {
+    throw new FormatException(message, uri, index);
+  }
+
+  static Uri _makeHttpUri(String scheme,
+                          String authority,
+                          String unencodedPath,
+                          Map<String, String> queryParameters) {
+    var userInfo = "";
+    var host = null;
+    var port = null;
+
+    if (authority != null && authority.isNotEmpty) {
+      var hostStart = 0;
+      // Split off the user info.
+      bool hasUserInfo = false;
+      for (int i = 0; i < authority.length; i++) {
+        if (authority.codeUnitAt(i) == _AT_SIGN) {
+          hasUserInfo = true;
+          userInfo = authority.substring(0, i);
+          hostStart = i + 1;
+          break;
+        }
+      }
+      var hostEnd = hostStart;
+      if (hostStart < authority.length &&
+          authority.codeUnitAt(hostStart) == _LEFT_BRACKET) {
+        // IPv6 host.
+        for (; hostEnd < authority.length; hostEnd++) {
+          if (authority.codeUnitAt(hostEnd) == _RIGHT_BRACKET) break;
+        }
+        if (hostEnd == authority.length) {
+          throw new FormatException("Invalid IPv6 host entry.",
+                                    authority, hostStart);
+        }
+        parseIPv6Address(authority, hostStart + 1, hostEnd);
+        hostEnd++;  // Skip the closing bracket.
+        if (hostEnd != authority.length &&
+            authority.codeUnitAt(hostEnd) != _COLON) {
+          throw new FormatException("Invalid end of authority",
+                                    authority, hostEnd);
+        }
+      }
+      // Split host and port.
+      bool hasPort = false;
+      for (; hostEnd < authority.length; hostEnd++) {
+        if (authority.codeUnitAt(hostEnd) == _COLON) {
+          var portString = authority.substring(hostEnd + 1);
+          // We allow the empty port - falling back to initial value.
+          if (portString.isNotEmpty) port = int.parse(portString);
+          break;
+        }
+      }
+      host = authority.substring(hostStart, hostEnd);
+    }
+    return new Uri(scheme: scheme,
+                   userInfo: userInfo,
+                   host: host,
+                   port: port,
+                   pathSegments: unencodedPath.split("/"),
+                   queryParameters: queryParameters);
+  }
 
   /**
    * Creates a new file URI from an absolute or relative file path.
@@ -254,7 +739,11 @@
    *
    * If the path passed is not a legal file path [ArgumentError] is thrown.
    */
-  factory Uri.file(String path, {bool windows}) = _Uri.file;
+  factory Uri.file(String path, {bool windows}) {
+    windows = (windows == null) ? Uri._isWindows : windows;
+    return windows ? _makeWindowsFileUrl(path, false)
+                   : _makeFileUri(path, false);
+  }
 
   /**
    * Like [Uri.file] except that a non-empty URI path ends in a slash.
@@ -263,7 +752,11 @@
    * then a slash is added to the returned URI's path.
    * In all other cases, the result is the same as returned by `Uri.file`.
    */
-  factory Uri.directory(String path, {bool windows}) = _Uri.directory;
+  factory Uri.directory(String path, {bool windows}) {
+    windows = (windows == null) ? Uri._isWindows : windows;
+    return windows ? _makeWindowsFileUrl(path, true)
+                   : _makeFileUri(path, true);
+  }
 
   /**
    * Creates a `data:` URI containing the [content] string.
@@ -334,1280 +827,16 @@
   }
 
   /**
-   * The scheme component of the URI.
+   * Returns the natural base URI for the current platform.
    *
-   * Returns the empty string if there is no scheme component.
+   * When running in a browser this is the current URL (from
+   * `window.location.href`).
    *
-   * A URI scheme is case insensitive.
-   * The returned scheme is canonicalized to lowercase letters.
+   * When not running in a browser this is the file URI referencing
+   * the current working directory.
    */
-  String get scheme;
-
-  /**
-   * Returns the authority component.
-   *
-   * The authority is formatted from the [userInfo], [host] and [port]
-   * parts.
-   *
-   * Returns the empty string if there is no authority component.
-   */
-  String get authority;
-
-  /**
-   * Returns the user info part of the authority component.
-   *
-   * Returns the empty string if there is no user info in the
-   * authority component.
-   */
-  String get userInfo;
-
-  /**
-   * Returns the host part of the authority component.
-   *
-   * Returns the empty string if there is no authority component and
-   * hence no host.
-   *
-   * If the host is an IP version 6 address, the surrounding `[` and `]` is
-   * removed.
-   *
-   * The host string is case-insensitive.
-   * The returned host name is canonicalized to lower-case
-   * with upper-case percent-escapes.
-   */
-  String get host;
-
-  /**
-   * Returns the port part of the authority component.
-   *
-   * Returns the defualt port if there is no port number in the authority
-   * component. That's 80 for http, 443 for https, and 0 for everything else.
-   */
-  int get port;
-
-  /**
-   * Returns the path component.
-   *
-   * The returned path is encoded. To get direct access to the decoded
-   * path use [pathSegments].
-   *
-   * Returns the empty string if there is no path component.
-   */
-  String get path;
-
-  /**
-   * Returns the query component. The returned query is encoded. To get
-   * direct access to the decoded query use [queryParameters].
-   *
-   * Returns the empty string if there is no query component.
-   */
-  String get query;
-
-  /**
-   * Returns the fragment identifier component.
-   *
-   * Returns the empty string if there is no fragment identifier
-   * component.
-   */
-  String get fragment;
-
-  /**
-   * Returns the URI path split into its segments. Each of the segments in the
-   * returned list have been decoded. If the path is empty the empty list will
-   * be returned. A leading slash `/` does not affect the segments returned.
-   *
-   * The returned list is unmodifiable and will throw [UnsupportedError] on any
-   * calls that would mutate it.
-   */
-  List<String> get pathSegments;
-
-  /**
-   * Returns the URI query split into a map according to the rules
-   * specified for FORM post in the [HTML 4.01 specification section
-   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
-   * Each key and value in the returned map has been decoded.
-   * If there is no query the empty map is returned.
-   *
-   * Keys in the query string that have no value are mapped to the
-   * empty string.
-   * If a key occurs more than once in the query string, it is mapped to
-   * an arbitrary choice of possible value.
-   * The [queryParametersAll] getter can provide a map
-   * that maps keys to all of their values.
-   *
-   * The returned map is unmodifiable.
-   */
-  Map<String, String> get queryParameters;
-
-  /**
-   * Returns the URI query split into a map according to the rules
-   * specified for FORM post in the [HTML 4.01 specification section
-   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
-   * Each key and value in the returned map has been decoded. If there is no
-   * query the empty map is returned.
-   *
-   * Keys are mapped to lists of their values. If a key occurs only once,
-   * its value is a singleton list. If a key occurs with no value, the
-   * empty string is used as the value for that occurrence.
-   *
-   * The returned map and the lists it contains are unmodifiable.
-   */
-  Map<String, List<String>> get queryParametersAll;
-
-  /**
-   * Returns whether the URI is absolute.
-   *
-   * A URI is an absolute URI in the sense of RFC 3986 if it has a scheme
-   * and no fragment.
-   */
-  bool get isAbsolute;
-
-  /**
-   * Returns whether the URI has a [scheme] component.
-   */
-  bool get hasScheme => scheme.isNotEmpty;
-
-  /**
-   * Returns whether the URI has an [authority] component.
-   */
-  bool get hasAuthority;
-
-  /**
-   * Returns whether the URI has an explicit port.
-   *
-   * If the port number is the default port number
-   * (zero for unrecognized schemes, with http (80) and https (443) being
-   * recognized),
-   * then the port is made implicit and omitted from the URI.
-   */
-  bool get hasPort;
-
-  /**
-   * Returns whether the URI has a query part.
-   */
-  bool get hasQuery;
-
-  /**
-   * Returns whether the URI has a fragment part.
-   */
-  bool get hasFragment;
-
-  /**
-   * Returns whether the URI has an empty path.
-   */
-  bool get hasEmptyPath;
-
-  /**
-   * Returns whether the URI has an absolute path (starting with '/').
-   */
-  bool get hasAbsolutePath;
-
-  /**
-   * Returns the origin of the URI in the form scheme://host:port for the
-   * schemes http and https.
-   *
-   * It is an error if the scheme is not "http" or "https".
-   *
-   * See: http://www.w3.org/TR/2011/WD-html5-20110405/origin-0.html#origin
-   */
-  String get origin;
-
-  /**
-   * Returns the file path from a file URI.
-   *
-   * The returned path has either Windows or non-Windows
-   * semantics.
-   *
-   * For non-Windows semantics the slash ("/") is used to separate
-   * path segments.
-   *
-   * For Windows semantics the backslash ("\") separator is used to
-   * separate path segments.
-   *
-   * If the URI is absolute the path starts with a path separator
-   * unless Windows semantics is used and the first path segment is a
-   * drive letter. When Windows semantics is used a host component in
-   * the uri in interpreted as a file server and a UNC path is
-   * returned.
-   *
-   * The default for whether to use Windows or non-Windows semantics
-   * determined from the platform Dart is running on. When running in
-   * the standalone VM this is detected by the VM based on the
-   * operating system. When running in a browser non-Windows semantics
-   * is always used.
-   *
-   * To override the automatic detection of which semantics to use pass
-   * a value for [windows]. Passing `true` will use Windows
-   * semantics and passing `false` will use non-Windows semantics.
-   *
-   * If the URI ends with a slash (i.e. the last path component is
-   * empty) the returned file path will also end with a slash.
-   *
-   * With Windows semantics URIs starting with a drive letter cannot
-   * be relative to the current drive on the designated drive. That is
-   * for the URI `file:///c:abc` calling `toFilePath` will throw as a
-   * path segment cannot contain colon on Windows.
-   *
-   * Examples using non-Windows semantics (resulting of calling
-   * toFilePath in comment):
-   *
-   *     Uri.parse("xxx/yyy");  // xxx/yyy
-   *     Uri.parse("xxx/yyy/");  // xxx/yyy/
-   *     Uri.parse("file:///xxx/yyy");  // /xxx/yyy
-   *     Uri.parse("file:///xxx/yyy/");  // /xxx/yyy/
-   *     Uri.parse("file:///C:");  // /C:
-   *     Uri.parse("file:///C:a");  // /C:a
-   *
-   * Examples using Windows semantics (resulting URI in comment):
-   *
-   *     Uri.parse("xxx/yyy");  // xxx\yyy
-   *     Uri.parse("xxx/yyy/");  // xxx\yyy\
-   *     Uri.parse("file:///xxx/yyy");  // \xxx\yyy
-   *     Uri.parse("file:///xxx/yyy/");  // \xxx\yyy/
-   *     Uri.parse("file:///C:/xxx/yyy");  // C:\xxx\yyy
-   *     Uri.parse("file:C:xxx/yyy");  // Throws as a path segment
-   *                                   // cannot contain colon on Windows.
-   *     Uri.parse("file://server/share/file");  // \\server\share\file
-   *
-   * If the URI is not a file URI calling this throws
-   * [UnsupportedError].
-   *
-   * If the URI cannot be converted to a file path calling this throws
-   * [UnsupportedError].
-   */
-  // TODO(lrn): Deprecate and move functionality to File class or similar.
-  // The core libraries should not worry about the platform.
-  String toFilePath({bool windows});
-
-  /**
-   * Access the structure of a `data:` URI.
-   *
-   * Returns a [UriData] object for `data:` URIs and `null` for all other
-   * URIs.
-   * The [UriData] object can be used to access the media type and data
-   * of a `data:` URI.
-   */
-  UriData get data;
-
-  /// Returns a hash code computed as `toString().hashCode`.
-  ///
-  /// This guarantees that URIs with the same normalized
-  int get hashCode;
-
-  /// A URI is equal to another URI with the same normalized representation.
-  bool operator==(Object other);
-
-  /// Returns the normalized string representation of the URI.
-  String toString();
-
-  /**
-   * Returns a new `Uri` based on this one, but with some parts replaced.
-   *
-   * This method takes the same parameters as the [new Uri] constructor,
-   * and they have the same meaning.
-   *
-   * At most one of [path] and [pathSegments] must be provided.
-   * Likewise, at most one of [query] and [queryParameters] must be provided.
-   *
-   * Each part that is not provided will default to the corresponding
-   * value from this `Uri` instead.
-   *
-   * This method is different from [Uri.resolve] which overrides in a
-   * hierarchial manner,
-   * and can instead replace each part of a `Uri` individually.
-   *
-   * Example:
-   *
-   *     Uri uri1 = Uri.parse("a://b@c:4/d/e?f#g");
-   *     Uri uri2 = uri1.replace(scheme: "A", path: "D/E/E", fragment: "G");
-   *     print(uri2);  // prints "A://b@c:4/D/E/E/?f#G"
-   *
-   * This method acts similarly to using the `new Uri` constructor with
-   * some of the arguments taken from this `Uri` . Example:
-   *
-   *     Uri uri3 = new Uri(
-   *         scheme: "A",
-   *         userInfo: uri1.userInfo,
-   *         host: uri1.host,
-   *         port: uri1.port,
-   *         path: "D/E/E",
-   *         query: uri1.query,
-   *         fragment: "G");
-   *     print(uri3);  // prints "A://b@c:4/D/E/E/?f#G"
-   *     print(uri2 == uri3);  // prints true.
-   *
-   * Using this method can be seen as a shorthand for the `Uri` constructor
-   * call above, but may also be slightly faster because the parts taken
-   * from this `Uri` need not be checked for validity again.
-   */
-  Uri replace({String scheme,
-               String userInfo,
-               String host,
-               int port,
-               String path,
-               Iterable<String> pathSegments,
-               String query,
-               Map<String, dynamic/*String|Iterable<String>*/> queryParameters,
-               String fragment});
-
-  /**
-   * Returns a `Uri` that differs from this only in not having a fragment.
-   *
-   * If this `Uri` does not have a fragment, it is itself returned.
-   */
-  Uri removeFragment();
-
-  /**
-   * Resolve [reference] as an URI relative to `this`.
-   *
-   * First turn [reference] into a URI using [Uri.parse]. Then resolve the
-   * resulting URI relative to `this`.
-   *
-   * Returns the resolved URI.
-   *
-   * See [resolveUri] for details.
-   */
-  Uri resolve(String reference);
-
-  /**
-   * Resolve [reference] as an URI relative to `this`.
-   *
-   * Returns the resolved URI.
-   *
-   * The algorithm "Transform Reference" for resolving a reference is described
-   * in [RFC-3986 Section 5](http://tools.ietf.org/html/rfc3986#section-5 "RFC-1123").
-   *
-   * Updated to handle the case where the base URI is just a relative path -
-   * that is: when it has no scheme or authority and the path does not start
-   * with a slash.
-   * In that case, the paths are combined without removing leading "..", and
-   * an empty path is not converted to "/".
-   */
-  Uri resolveUri(Uri reference);
-
-  /**
-   * Returns a URI where the path has been normalized.
-   *
-   * A normalized path does not contain `.` segments or non-leading `..`
-   * segments.
-   * Only a relative path with no scheme or authority may contain
-   * leading `..` segments,
-   * a path that starts with `/` will also drop any leading `..` segments.
-   *
-   * This uses the same normalization strategy as `new Uri().resolve(this)`.
-   *
-   * Does not change any part of the URI except the path.
-   *
-   * The default implementation of `Uri` always normalizes paths, so calling
-   * this function has no effect.
-   */
-  Uri normalizePath();
-
-  /**
-   * Creates a new `Uri` object by parsing a URI string.
-   *
-   * If [start] and [end] are provided, only the substring from `start`
-   * to `end` is parsed as a URI.
-   *
-   * If the string is not valid as a URI or URI reference,
-   * a [FormatException] is thrown.
-   */
-  static Uri parse(String uri, [int start = 0, int end]) {
-    // This parsing will not validate percent-encoding, IPv6, etc.
-    // When done splitting into parts, it will call, e.g., [_makeFragment]
-    // to do the final parsing.
-    //
-    // Important parts of the RFC 3986 used here:
-    // URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
-    //
-    // hier-part     = "//" authority path-abempty
-    //               / path-absolute
-    //               / path-rootless
-    //               / path-empty
-    //
-    // URI-reference = URI / relative-ref
-    //
-    // absolute-URI  = scheme ":" hier-part [ "?" query ]
-    //
-    // relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
-    //
-    // relative-part = "//" authority path-abempty
-    //               / path-absolute
-    //               / path-noscheme
-    //               / path-empty
-    //
-    // scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-    //
-    // authority     = [ userinfo "@" ] host [ ":" port ]
-    // userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
-    // host          = IP-literal / IPv4address / reg-name
-    // port          = *DIGIT
-    // reg-name      = *( unreserved / pct-encoded / sub-delims )
-    //
-    // path          = path-abempty    ; begins with "/" or is empty
-    //               / path-absolute   ; begins with "/" but not "//"
-    //               / path-noscheme   ; begins with a non-colon segment
-    //               / path-rootless   ; begins with a segment
-    //               / path-empty      ; zero characters
-    //
-    // path-abempty  = *( "/" segment )
-    // path-absolute = "/" [ segment-nz *( "/" segment ) ]
-    // path-noscheme = segment-nz-nc *( "/" segment )
-    // path-rootless = segment-nz *( "/" segment )
-    // path-empty    = 0<pchar>
-    //
-    // segment       = *pchar
-    // segment-nz    = 1*pchar
-    // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
-    //               ; non-zero-length segment without any colon ":"
-    //
-    // pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
-    //
-    // query         = *( pchar / "/" / "?" )
-    //
-    // fragment      = *( pchar / "/" / "?" )
-    end ??= uri.length;
-
-    // Special case data:URIs. Ignore case when testing.
-    if (end >= start + 5) {
-      int dataDelta = _startsWithData(uri, start);
-      if (dataDelta == 0) {
-        // The case is right.
-        if (start > 0 || end < uri.length) uri = uri.substring(start, end);
-        return UriData._parse(uri, 5, null).uri;
-      } else if (dataDelta == 0x20) {
-        return UriData._parse(uri.substring(start + 5, end), 0, null).uri;
-      }
-      // Otherwise the URI doesn't start with "data:" or any case variant of it.
-    }
-
-    // The following index-normalization belongs with the scanning, but is
-    // easier to do here because we already have extracted variables from the
-    // indices list.
-    var indices = new List<int>(8);//new List<int>.filled(8, start - 1);
-
-    // Set default values for each position.
-    // The value will either be correct in some cases where it isn't set
-    // by the scanner, or it is clearly recognizable as an unset value.
-    indices
-      ..[0] = 0
-      ..[_schemeEndIndex] = start - 1
-      ..[_hostStartIndex] = start - 1
-      ..[_notSimpleIndex] = start - 1
-      ..[_portStartIndex] = start
-      ..[_pathStartIndex] = start
-      ..[_queryStartIndex] = end
-      ..[_fragmentStartIndex] = end;
-    var state = _scan(uri, start, end, _uriStart, indices);
-    // Some states that should be non-simple, but the URI ended early.
-    // Paths that end at a ".." must be normalized to end in "../".
-    if (state >= _nonSimpleEndStates) {
-      indices[_notSimpleIndex] = end;
-    }
-    int schemeEnd = indices[_schemeEndIndex];
-    if (schemeEnd >= start) {
-      // Rescan the scheme part now that we know it's not a path.
-      state = _scan(uri, start, schemeEnd, _schemeStart, indices);
-      if (state == _schemeStart) {
-        // Empty scheme.
-        indices[_notSimpleIndex] = schemeEnd;
-      }
-    }
-    // The returned positions are limited by the scanners ability to write only
-    // one position per character, and only the current position.
-    // Scanning from left to right, we only know whether something is a scheme
-    // or a path when we see a `:` or `/`, and likewise we only know if the first
-    // `/` is part of the path or is leading an authority component when we see
-    // the next character.
-
-    int hostStart     = indices[_hostStartIndex] + 1;
-    int portStart     = indices[_portStartIndex];
-    int pathStart     = indices[_pathStartIndex];
-    int queryStart    = indices[_queryStartIndex];
-    int fragmentStart = indices[_fragmentStartIndex];
-
-    // We may discover scheme while handling special cases.
-    String scheme;
-
-    // Derive some positions that weren't set to normalize the indices.
-    // If pathStart isn't set (it's before scheme end or host start), then
-    // the path is empty.
-    if (fragmentStart < queryStart) queryStart = fragmentStart;
-    if (pathStart < hostStart || pathStart <= schemeEnd) {
-      pathStart = queryStart;
-    }
-    // If there is an authority with no port, set the port position
-    // to be at the end of the authority (equal to pathStart).
-    // This also handles a ":" in a user-info component incorrectly setting
-    // the port start position.
-    if (portStart < hostStart) portStart = pathStart;
-
-    assert(hostStart == start || schemeEnd <= hostStart);
-    assert(hostStart <= portStart);
-    assert(schemeEnd <= pathStart);
-    assert(portStart <= pathStart);
-    assert(pathStart <= queryStart);
-    assert(queryStart <= fragmentStart);
-
-    bool isSimple = indices[_notSimpleIndex] < start;
-
-    if (isSimple) {
-      // Check/do normalizations that weren't detected by the scanner.
-      // This includes removal of empty port or userInfo,
-      // or scheme specific port and path normalizations.
-      if (hostStart > schemeEnd + 3) {
-        // Always be non-simple if URI contains user-info.
-        // The scanner doesn't set the not-simple position in this case because
-        // it's setting the host-start position instead.
-        isSimple = false;
-      } else if (portStart > start && portStart + 1 == pathStart) {
-        // If the port is empty, it should be omitted.
-        // Pathological case, don't bother correcting it.
-        isSimple = false;
-      } else if (queryStart < end &&
-                 (queryStart == pathStart + 2 &&
-                  uri.startsWith("..", pathStart)) ||
-                 (queryStart > pathStart + 2 &&
-                  uri.startsWith("/..", queryStart - 3))) {
-        // The path ends in a ".." segment. This should be normalized to "../".
-        // We didn't detect this while scanning because a query or fragment was
-        // detected at the same time (which is why we only need to check this
-        // if there is something after the path).
-        isSimple = false;
-      } else {
-        // There are a few scheme-based normalizations that
-        // the scanner couldn't check.
-        // That means that the input is very close to simple, so just do
-        // the normalizations.
-        if (schemeEnd == start + 4) {
-          // Do scheme based normalizations for file, http.
-          if (uri.startsWith("file", start)) {
-            scheme = "file";
-            if (hostStart <= start) {
-              // File URIs should have an authority.
-              // Paths after an authority should be absolute.
-              String schemeAuth = "file://";
-              int delta = 2;
-              if (!uri.startsWith("/", pathStart)) {
-                schemeAuth = "file:///";
-                delta = 3;
-              }
-              uri = schemeAuth + uri.substring(pathStart, end);
-              schemeEnd -= start;
-              hostStart = 7;
-              portStart = 7;
-              pathStart = 7;
-              queryStart += delta - start;
-              fragmentStart += delta - start;
-              start = 0;
-              end = uri.length;
-            } else if (pathStart == queryStart) {
-              // Uri has authority and empty path. Add "/" as path.
-              if (start == 0 && end == uri.length) {
-                uri = uri.replaceRange(pathStart, queryStart, "/");
-                queryStart += 1;
-                fragmentStart += 1;
-                end += 1;
-              } else {
-                uri = "${uri.substring(start, pathStart)}/"
-                      "${uri.substring(queryStart, end)}";
-                schemeEnd -= start;
-                hostStart -= start;
-                portStart -= start;
-                pathStart -= start;
-                queryStart += 1 - start;
-                fragmentStart += 1 - start;
-                start = 0;
-                end = uri.length;
-              }
-            }
-          } else if (uri.startsWith("http", start)) {
-            scheme = "http";
-            // HTTP URIs should not have an explicit port of 80.
-            if (portStart > start && portStart + 3 == pathStart &&
-                uri.startsWith("80", portStart + 1)) {
-              if (start == 0 && end == uri.length) {
-                uri = uri.replaceRange(portStart, pathStart, "");
-                pathStart -= 3;
-                queryStart -= 3;
-                fragmentStart -= 3;
-                end -= 3;
-              } else {
-                uri = uri.substring(start, portStart) +
-                      uri.substring(pathStart, end);
-                schemeEnd -= start;
-                hostStart -= start;
-                portStart -= start;
-                pathStart -= 3 + start;
-                queryStart -= 3 + start;
-                fragmentStart -= 3 + start;
-                start = 0;
-                end = uri.length;
-              }
-            }
-          }
-        } else if (schemeEnd == start + 5 && uri.startsWith("https", start)) {
-          scheme = "https";
-          // HTTPS URIs should not have an explicit port of 443.
-          if (portStart > start && portStart + 4 == pathStart &&
-              uri.startsWith("443", portStart + 1)) {
-            if (start == 0 && end == uri.length) {
-              uri = uri.replaceRange(portStart, pathStart, "");
-              pathStart -= 4;
-              queryStart -= 4;
-              fragmentStart -= 4;
-              end -= 3;
-            } else {
-              uri = uri.substring(start, portStart) +
-                    uri.substring(pathStart, end);
-              schemeEnd -= start;
-              hostStart -= start;
-              portStart -= start;
-              pathStart -= 4 + start;
-              queryStart -= 4 + start;
-              fragmentStart -= 4 + start;
-              start = 0;
-              end = uri.length;
-            }
-          }
-        }
-      }
-    }
-
-    if (isSimple) {
-      if (start > 0 || end < uri.length) {
-        uri = uri.substring(start, end);
-        schemeEnd -= start;
-        hostStart -= start;
-        portStart -= start;
-        pathStart -= start;
-        queryStart -= start;
-        fragmentStart -= start;
-      }
-      return new _SimpleUri(uri, schemeEnd, hostStart, portStart, pathStart,
-                            queryStart, fragmentStart, scheme);
-
-    }
-
-    return new _Uri.notSimple(uri, start, end, schemeEnd, hostStart, portStart,
-                              pathStart, queryStart, fragmentStart, scheme);
-  }
-
-  /**
-   * Encode the string [component] using percent-encoding to make it
-   * safe for literal use as a URI component.
-   *
-   * All characters except uppercase and lowercase letters, digits and
-   * the characters `-_.!~*'()` are percent-encoded. This is the
-   * set of characters specified in RFC 2396 and the which is
-   * specified for the encodeUriComponent in ECMA-262 version 5.1.
-   *
-   * When manually encoding path segments or query components remember
-   * to encode each part separately before building the path or query
-   * string.
-   *
-   * For encoding the query part consider using
-   * [encodeQueryComponent].
-   *
-   * To avoid the need for explicitly encoding use the [pathSegments]
-   * and [queryParameters] optional named arguments when constructing
-   * a [Uri].
-   */
-  static String encodeComponent(String component) {
-    return _Uri._uriEncode(_Uri._unreserved2396Table, component, UTF8, false);
-  }
-
-  /**
-   * Encode the string [component] according to the HTML 4.01 rules
-   * for encoding the posting of a HTML form as a query string
-   * component.
-   *
-   * Encode the string [component] according to the HTML 4.01 rules
-   * for encoding the posting of a HTML form as a query string
-   * component.
-
-   * The component is first encoded to bytes using [encoding].
-   * The default is to use [UTF8] encoding, which preserves all
-   * the characters that don't need encoding.
-
-   * Then the resulting bytes are "percent-encoded". This transforms
-   * spaces (U+0020) to a plus sign ('+') and all bytes that are not
-   * the ASCII decimal digits, letters or one of '-._~' are written as
-   * a percent sign '%' followed by the two-digit hexadecimal
-   * representation of the byte.
-
-   * Note that the set of characters which are percent-encoded is a
-   * superset of what HTML 4.01 requires, since it refers to RFC 1738
-   * for reserved characters.
-   *
-   * When manually encoding query components remember to encode each
-   * part separately before building the query string.
-   *
-   * To avoid the need for explicitly encoding the query use the
-   * [queryParameters] optional named arguments when constructing a
-   * [Uri].
-   *
-   * See http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 for more
-   * details.
-   */
-  static String encodeQueryComponent(String component,
-                                     {Encoding encoding: UTF8}) {
-    return _Uri._uriEncode(_Uri._unreservedTable, component, encoding, true);
-  }
-
-  /**
-   * Decodes the percent-encoding in [encodedComponent].
-   *
-   * Note that decoding a URI component might change its meaning as
-   * some of the decoded characters could be characters with are
-   * delimiters for a given URI componene type. Always split a URI
-   * component using the delimiters for the component before decoding
-   * the individual parts.
-   *
-   * For handling the [path] and [query] components consider using
-   * [pathSegments] and [queryParameters] to get the separated and
-   * decoded component.
-   */
-  static String decodeComponent(String encodedComponent) {
-    return _Uri._uriDecode(encodedComponent, 0, encodedComponent.length,
-                           UTF8, false);
-  }
-
-  /**
-   * Decodes the percent-encoding in [encodedComponent], converting
-   * pluses to spaces.
-   *
-   * It will create a byte-list of the decoded characters, and then use
-   * [encoding] to decode the byte-list to a String. The default encoding is
-   * UTF-8.
-   */
-  static String decodeQueryComponent(
-      String encodedComponent,
-      {Encoding encoding: UTF8}) {
-    return _Uri._uriDecode(encodedComponent, 0, encodedComponent.length,
-                           encoding, true);
-  }
-
-  /**
-   * Encode the string [uri] using percent-encoding to make it
-   * safe for literal use as a full URI.
-   *
-   * All characters except uppercase and lowercase letters, digits and
-   * the characters `!#$&'()*+,-./:;=?@_~` are percent-encoded. This
-   * is the set of characters specified in in ECMA-262 version 5.1 for
-   * the encodeURI function .
-   */
-  static String encodeFull(String uri) {
-    return _Uri._uriEncode(_Uri._encodeFullTable, uri, UTF8, false);
-  }
-
-  /**
-   * Decodes the percent-encoding in [uri].
-   *
-   * Note that decoding a full URI might change its meaning as some of
-   * the decoded characters could be reserved characters. In most
-   * cases an encoded URI should be parsed into components using
-   * [Uri.parse] before decoding the separate components.
-   */
-  static String decodeFull(String uri) {
-    return _Uri._uriDecode(uri, 0, uri.length, UTF8, false);
-  }
-
-  /**
-   * Returns the [query] split into a map according to the rules
-   * specified for FORM post in the [HTML 4.01 specification section
-   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
-   * Each key and value in the returned map has been decoded. If the [query]
-   * is the empty string an empty map is returned.
-   *
-   * Keys in the query string that have no value are mapped to the
-   * empty string.
-   *
-   * Each query component will be decoded using [encoding]. The default encoding
-   * is UTF-8.
-   */
-  static Map<String, String> splitQueryString(String query,
-                                              {Encoding encoding: UTF8}) {
-    return query.split("&").fold({}, (map, element) {
-      int index = element.indexOf("=");
-      if (index == -1) {
-        if (element != "") {
-          map[decodeQueryComponent(element, encoding: encoding)] = "";
-        }
-      } else if (index != 0) {
-        var key = element.substring(0, index);
-        var value = element.substring(index + 1);
-        map[decodeQueryComponent(key, encoding: encoding)] =
-            decodeQueryComponent(value, encoding: encoding);
-      }
-      return map;
-    });
-  }
-
-
-  /**
-   * Parse the [host] as an IP version 4 (IPv4) address, returning the address
-   * as a list of 4 bytes in network byte order (big endian).
-   *
-   * Throws a [FormatException] if [host] is not a valid IPv4 address
-   * representation.
-   */
-  static List<int> parseIPv4Address(String host) =>
-       _parseIPv4Address(host, 0, host.length);
-
-  /// Implementation of [parseIPv4Address] that can work on a substring.
-  static List<int> _parseIPv4Address(String host, int start, int end) {
-    void error(String msg, int position) {
-      throw new FormatException('Illegal IPv4 address, $msg', host, position);
-    }
-
-    var result = new Uint8List(4);
-    int partIndex = 0;
-    int partStart = start;
-    for (int i = start; i < end; i++) {
-      int char = host.codeUnitAt(i);
-      if (char != _DOT) {
-        if (char ^ 0x30 > 9) {
-          // Fail on a non-digit character.
-          error("invalid character", i);
-        }
-      } else {
-        if (partIndex == 3) {
-          error('IPv4 address should contain exactly 4 parts', i);
-        }
-        int part = int.parse(host.substring(partStart, i));
-        if (part > 255) {
-          error("each part must be in the range 0..255", partStart);
-        }
-        result[partIndex++] = part;
-        partStart = i + 1;
-      }
-    }
-
-    if (partIndex != 3) {
-      error('IPv4 address should contain exactly 4 parts', end);
-    }
-
-    int part = int.parse(host.substring(partStart, end));
-    if (part > 255) {
-      error("each part must be in the range 0..255", partStart);
-    }
-    result[partIndex] = part;
-
-    return result;
-  }
-
-  /**
-   * Parse the [host] as an IP version 6 (IPv6) address, returning the address
-   * as a list of 16 bytes in network byte order (big endian).
-   *
-   * Throws a [FormatException] if [host] is not a valid IPv6 address
-   * representation.
-   *
-   * Acts on the substring from [start] to [end]. If [end] is omitted, it
-   * defaults ot the end of the string.
-   *
-   * Some examples of IPv6 addresses:
-   *  * ::1
-   *  * FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
-   *  * 3ffe:2a00:100:7031::1
-   *  * ::FFFF:129.144.52.38
-   *  * 2010:836B:4179::836B:4179
-   */
-  static List<int> parseIPv6Address(String host, [int start = 0, int end]) {
-    if (end == null) end = host.length;
-    // An IPv6 address consists of exactly 8 parts of 1-4 hex digits, separated
-    // by `:`'s, with the following exceptions:
-    //
-    //  - One (and only one) wildcard (`::`) may be present, representing a fill
-    //    of 0's. The IPv6 `::` is thus 16 bytes of `0`.
-    //  - The last two parts may be replaced by an IPv4 "dotted-quad" address.
-
-    // Helper function for reporting a badly formatted IPv6 address.
-    void error(String msg, [position]) {
-      throw new FormatException('Illegal IPv6 address, $msg', host, position);
-    }
-
-    // Parse a hex block.
-    int parseHex(int start, int end) {
-      if (end - start > 4) {
-        error('an IPv6 part can only contain a maximum of 4 hex digits', start);
-      }
-      int value = int.parse(host.substring(start, end), radix: 16);
-      if (value < 0 || value > 0xFFFF) {
-        error('each part must be in the range of `0x0..0xFFFF`', start);
-      }
-      return value;
-    }
-
-    if (host.length < 2) error('address is too short');
-    List<int> parts = [];
-    bool wildcardSeen = false;
-    // Set if seeing a ".", suggesting that there is an IPv4 address.
-    bool seenDot = false;
-    int partStart = start;
-    // Parse all parts, except a potential last one.
-    for (int i = start; i < end; i++) {
-      int char = host.codeUnitAt(i);
-      if (char == _COLON) {
-        if (i == start) {
-          // If we see a `:` in the beginning, expect wildcard.
-          i++;
-          if (host.codeUnitAt(i) != _COLON) {
-            error('invalid start colon.', i);
-          }
-          partStart = i;
-        }
-        if (i == partStart) {
-          // Wildcard. We only allow one.
-          if (wildcardSeen) {
-            error('only one wildcard `::` is allowed', i);
-          }
-          wildcardSeen = true;
-          parts.add(-1);
-        } else {
-          // Found a single colon. Parse [partStart..i] as a hex entry.
-          parts.add(parseHex(partStart, i));
-        }
-        partStart = i + 1;
-      } else if (char == _DOT) {
-        seenDot = true;
-      }
-    }
-    if (parts.length == 0) error('too few parts');
-    bool atEnd = (partStart == end);
-    bool isLastWildcard = (parts.last == -1);
-    if (atEnd && !isLastWildcard) {
-      error('expected a part after last `:`', end);
-    }
-    if (!atEnd) {
-      if (!seenDot) {
-        parts.add(parseHex(partStart, end));
-      } else {
-        List<int> last = _parseIPv4Address(host, partStart, end);
-        parts.add(last[0] << 8 | last[1]);
-        parts.add(last[2] << 8 | last[3]);
-      }
-    }
-    if (wildcardSeen) {
-      if (parts.length > 7) {
-        error('an address with a wildcard must have less than 7 parts');
-      }
-    } else if (parts.length != 8) {
-      error('an address without a wildcard must contain exactly 8 parts');
-    }
-    List<int> bytes = new Uint8List(16);
-    for (int i = 0, index = 0; i < parts.length; i++) {
-      int value = parts[i];
-      if (value == -1) {
-        int wildCardLength = 9 - parts.length;
-        for (int j = 0; j < wildCardLength; j++) {
-          bytes[index] = 0;
-          bytes[index + 1] = 0;
-          index += 2;
-        }
-      } else {
-        bytes[index] = value >> 8;
-        bytes[index + 1] = value & 0xff;
-        index += 2;
-      }
-    }
-    return bytes;
-  }
-}
-
-class _Uri implements Uri {
-  // We represent the missing scheme as an empty string.
-  // A valid scheme cannot be empty.
-  final String scheme;
-
-  /**
-   * The user-info part of the authority.
-   *
-   * Does not distinguish between an empty user-info and an absent one.
-   * The value is always non-null.
-   * Is considered absent if [_host] is `null`.
-   */
-  final String _userInfo;
-
-  /**
-   * The host name of the URI.
-   *
-   * Set to `null` if there is no authority in the URI.
-   * The host name is the only mandatory part of an authority, so we use
-   * it to mark whether an authority part was present or not.
-   */
-  final String _host;
-
-  /**
-   * The port number part of the authority.
-   *
-   * The port. Set to null if there is no port. Normalized to null if
-   * the port is the default port for the scheme.
-   */
-  int _port;
-
-  /**
-   * The path of the URI.
-   *
-   * Always non-null.
-   */
-  String _path;
-
-  // The query content, or null if there is no query.
-  final String _query;
-
-  // The fragment content, or null if there is no fragment.
-  final String _fragment;
-
-  /**
-   * Cache the computed return value of [pathSegements].
-   */
-  List<String> _pathSegments;
-
-  /**
-   * Cache of the full normalized text representation of the URI.
-   */
-  String _text;
-
-  /**
-   * Cache of the hashCode of [_text].
-   *
-   * Is null until computed.
-   */
-  int _hashCodeCache;
-
-  /**
-   * Cache the computed return value of [queryParameters].
-   */
-  Map<String, String> _queryParameters;
-  Map<String, List<String>> _queryParameterLists;
-
-  /// Internal non-verifying constructor. Only call with validated arguments.
-  _Uri._internal(this.scheme,
-                 this._userInfo,
-                 this._host,
-                 this._port,
-                 this._path,
-                 this._query,
-                 this._fragment);
-
-  /// Create a [_Uri] from parts of [uri].
-  ///
-  /// The parameters specify the start/end of particular components of the URI.
-  /// The [scheme] may contain a string representing a normalized scheme
-  /// component if one has already been discovered.
-  factory _Uri.notSimple(String uri, int start, int end, int schemeEnd,
-                        int hostStart, int portStart, int pathStart,
-                        int queryStart, int fragmentStart, String scheme) {
-    if (scheme == null) {
-      scheme = "";
-      if (schemeEnd > start) {
-        scheme = _makeScheme(uri, start, schemeEnd);
-      } else if (schemeEnd == start) {
-        _fail(uri, start, "Invalid empty scheme");
-      }
-    }
-    String userInfo = "";
-    String host;
-    int port;
-    if (hostStart > start) {
-      int userInfoStart = schemeEnd + 3;
-      if (userInfoStart < hostStart) {
-        userInfo = _makeUserInfo(uri, userInfoStart, hostStart - 1);
-      }
-      host = _makeHost(uri, hostStart, portStart, false);
-      if (portStart + 1 < pathStart) {
-        // Should throw because invalid.
-        port = int.parse(uri.substring(portStart + 1, pathStart), onError: (_) {
-          throw new FormatException("Invalid port", uri, portStart + 1);
-        });
-        port = _makePort(port, scheme);
-      }
-    }
-    String path = _makePath(uri, pathStart, queryStart, null,
-                            scheme, host != null);
-    String query;
-    if (queryStart < fragmentStart) {
-      query = _makeQuery(uri, queryStart + 1, fragmentStart, null);
-    }
-    String fragment;
-    if (fragmentStart < end) {
-      fragment = _makeFragment(uri, fragmentStart + 1, end);
-    }
-    return new _Uri._internal(scheme,
-                              userInfo,
-                              host,
-                              port,
-                              path,
-                              query,
-                              fragment);
-  }
-
-  /// Implementation of [Uri.Uri].
-  factory _Uri({String scheme,
-                String userInfo,
-                String host,
-                int port,
-                String path,
-                Iterable<String> pathSegments,
-                String query,
-                Map<String, dynamic/*String|Iterable<String>*/> queryParameters,
-                String fragment}) {
-    scheme = _makeScheme(scheme, 0, _stringOrNullLength(scheme));
-    userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo));
-    host = _makeHost(host, 0, _stringOrNullLength(host), false);
-    // Special case this constructor for backwards compatibility.
-    if (query == "") query = null;
-    query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters);
-    fragment = _makeFragment(fragment, 0, _stringOrNullLength(fragment));
-    port = _makePort(port, scheme);
-    bool isFile = (scheme == "file");
-    if (host == null &&
-        (userInfo.isNotEmpty || port != null || isFile)) {
-      host = "";
-    }
-    bool hasAuthority = (host != null);
-    path = _makePath(path, 0, _stringOrNullLength(path), pathSegments,
-                     scheme, hasAuthority);
-    if (scheme.isEmpty && host == null && !path.startsWith('/')) {
-      path = _normalizeRelativePath(path);
-    } else {
-      path = _removeDotSegments(path);
-    }
-    return new _Uri._internal(scheme, userInfo, host, port,
-                              path, query, fragment);
-  }
-
-  /// Implementation of [Uri.http].
-  factory _Uri.http(String authority,
-                    String unencodedPath,
-                    [Map<String, String> queryParameters]) {
-    return _makeHttpUri("http", authority, unencodedPath, queryParameters);
-  }
-
-  /// Implementation of [Uri.https].
-  factory _Uri.https(String authority,
-                     String unencodedPath,
-                     [Map<String, String> queryParameters]) {
-    return _makeHttpUri("https", authority, unencodedPath, queryParameters);
-  }
-
-  String get authority {
-    if (!hasAuthority) return "";
-    var sb = new StringBuffer();
-    _writeAuthority(sb);
-    return sb.toString();
-  }
-
-  String get userInfo => _userInfo;
-
-  String get host {
-    if (_host == null) return "";
-    if (_host.startsWith('[')) {
-      return _host.substring(1, _host.length - 1);
-    }
-    return _host;
-  }
-
-  int get port {
-    if (_port == null) return _defaultPort(scheme);
-    return _port;
-  }
-
-  // The default port for the scheme of this Uri.
-  static int _defaultPort(String scheme) {
-    if (scheme == "http") return 80;
-    if (scheme == "https") return 443;
-    return 0;
-  }
-
-  String get path => _path;
-
-  String get query => _query ?? "";
-
-  String get fragment => _fragment ?? "";
-
-  // Report a parse failure.
-  static void _fail(String uri, int index, String message) {
-    throw new FormatException(message, uri, index);
-  }
-
-  static Uri _makeHttpUri(String scheme,
-                          String authority,
-                          String unencodedPath,
-                          Map<String, String> queryParameters) {
-    var userInfo = "";
-    var host = null;
-    var port = null;
-
-    if (authority != null && authority.isNotEmpty) {
-      var hostStart = 0;
-      // Split off the user info.
-      bool hasUserInfo = false;
-      for (int i = 0; i < authority.length; i++) {
-        const int atSign = 0x40;
-        if (authority.codeUnitAt(i) == atSign) {
-          hasUserInfo = true;
-          userInfo = authority.substring(0, i);
-          hostStart = i + 1;
-          break;
-        }
-      }
-      var hostEnd = hostStart;
-      if (hostStart < authority.length &&
-          authority.codeUnitAt(hostStart) == _LEFT_BRACKET) {
-        // IPv6 host.
-        for (; hostEnd < authority.length; hostEnd++) {
-          if (authority.codeUnitAt(hostEnd) == _RIGHT_BRACKET) break;
-        }
-        if (hostEnd == authority.length) {
-          throw new FormatException("Invalid IPv6 host entry.",
-                                    authority, hostStart);
-        }
-        Uri.parseIPv6Address(authority, hostStart + 1, hostEnd);
-        hostEnd++;  // Skip the closing bracket.
-        if (hostEnd != authority.length &&
-            authority.codeUnitAt(hostEnd) != _COLON) {
-          throw new FormatException("Invalid end of authority",
-                                    authority, hostEnd);
-        }
-      }
-      // Split host and port.
-      bool hasPort = false;
-      for (; hostEnd < authority.length; hostEnd++) {
-        if (authority.codeUnitAt(hostEnd) == _COLON) {
-          var portString = authority.substring(hostEnd + 1);
-          // We allow the empty port - falling back to initial value.
-          if (portString.isNotEmpty) port = int.parse(portString);
-          break;
-        }
-      }
-      host = authority.substring(hostStart, hostEnd);
-    }
-    return new Uri(scheme: scheme,
-                   userInfo: userInfo,
-                   host: host,
-                   port: port,
-                   pathSegments: unencodedPath.split("/"),
-                   queryParameters: queryParameters);
-  }
-
-  /// Implementation of [Uri.file].
-  factory _Uri.file(String path, {bool windows}) {
-    windows = (windows == null) ? _Uri._isWindows : windows;
-    return windows ? _makeWindowsFileUrl(path, false)
-                   : _makeFileUri(path, false);
-  }
-
-  /// Implementation of [Uri.directory].
-  factory _Uri.directory(String path, {bool windows}) {
-    windows = (windows == null) ? _Uri._isWindows : windows;
-    return windows ? _makeWindowsFileUrl(path, true)
-                   : _makeFileUri(path, true);
-  }
-
+  external static Uri get base;
 
-  /// Used internally in path-related constructors.
   external static bool get _isWindows;
 
   static _checkNonWindowsPathReservedCharacters(List<String> segments,
@@ -1740,6 +969,46 @@
     }
   }
 
+  /**
+   * Returns a new `Uri` based on this one, but with some parts replaced.
+   *
+   * This method takes the same parameters as the [new Uri] constructor,
+   * and they have the same meaning.
+   *
+   * At most one of [path] and [pathSegments] must be provided.
+   * Likewise, at most one of [query] and [queryParameters] must be provided.
+   *
+   * Each part that is not provided will default to the corresponding
+   * value from this `Uri` instead.
+   *
+   * This method is different from [Uri.resolve] which overrides in a
+   * hierarchial manner,
+   * and can instead replace each part of a `Uri` individually.
+   *
+   * Example:
+   *
+   *     Uri uri1 = Uri.parse("a://b@c:4/d/e?f#g");
+   *     Uri uri2 = uri1.replace(scheme: "A", path: "D/E/E", fragment: "G");
+   *     print(uri2);  // prints "A://b@c:4/D/E/E/?f#G"
+   *
+   * This method acts similarly to using the `new Uri` constructor with
+   * some of the arguments taken from this `Uri` . Example:
+   *
+   *     Uri uri3 = new Uri(
+   *         scheme: "A",
+   *         userInfo: uri1.userInfo,
+   *         host: uri1.host,
+   *         port: uri1.port,
+   *         path: "D/E/E",
+   *         query: uri1.query,
+   *         fragment: "G");
+   *     print(uri3);  // prints "A://b@c:4/D/E/E/?f#G"
+   *     print(uri2 == uri3);  // prints true.
+   *
+   * Using this method can be seen as a shorthand for the `Uri` constructor
+   * call above, but may also be slightly faster because the parts taken
+   * from this `Uri` need not be checked for validity again.
+   */
   Uri replace({String scheme,
                String userInfo,
                String host,
@@ -1806,16 +1075,29 @@
       fragment = this._fragment;
     }
 
-    return new _Uri._internal(
+    return new Uri._internal(
         scheme, userInfo, host, port, path, query, fragment);
   }
 
+  /**
+   * Returns a `Uri` that differs from this only in not having a fragment.
+   *
+   * If this `Uri` does not have a fragment, it is itself returned.
+   */
   Uri removeFragment() {
     if (!this.hasFragment) return this;
-    return new _Uri._internal(scheme, _userInfo, _host, _port,
+    return new Uri._internal(scheme, _userInfo, _host, _port,
                              _path, _query, null);
   }
 
+  /**
+   * Returns the URI path split into its segments. Each of the segments in the
+   * returned list have been decoded. If the path is empty the empty list will
+   * be returned. A leading slash `/` does not affect the segments returned.
+   *
+   * The returned list is unmodifiable and will throw [UnsupportedError] on any
+   * calls that would mutate it.
+   */
   List<String> get pathSegments {
     var result = _pathSegments;
     if (result != null) return result;
@@ -1832,14 +1114,43 @@
     return result;
   }
 
+  /**
+   * Returns the URI query split into a map according to the rules
+   * specified for FORM post in the [HTML 4.01 specification section
+   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
+   * Each key and value in the returned map has been decoded.
+   * If there is no query the empty map is returned.
+   *
+   * Keys in the query string that have no value are mapped to the
+   * empty string.
+   * If a key occurs more than once in the query string, it is mapped to
+   * an arbitrary choice of possible value.
+   * The [queryParametersAll] getter can provide a map
+   * that maps keys to all of their values.
+   *
+   * The returned map is unmodifiable.
+   */
   Map<String, String> get queryParameters {
     if (_queryParameters == null) {
       _queryParameters =
-          new UnmodifiableMapView<String, String>(Uri.splitQueryString(query));
+          new UnmodifiableMapView<String, String>(splitQueryString(query));
     }
     return _queryParameters;
   }
 
+  /**
+   * Returns the URI query split into a map according to the rules
+   * specified for FORM post in the [HTML 4.01 specification section
+   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
+   * Each key and value in the returned map has been decoded. If there is no
+   * query the empty map is returned.
+   *
+   * Keys are mapped to lists of their values. If a key occurs only once,
+   * its value is a singleton list. If a key occurs with no value, the
+   * empty string is used as the value for that occurrence.
+   *
+   * The returned map and the lists it contains are unmodifiable.
+   */
   Map<String, List<String>> get queryParametersAll {
     if (_queryParameterLists == null) {
       Map queryParameterLists = _splitQueryStringAll(query);
@@ -1853,6 +1164,22 @@
     return _queryParameterLists;
   }
 
+  /**
+   * Returns a URI where the path has been normalized.
+   *
+   * A normalized path does not contain `.` segments or non-leading `..`
+   * segments.
+   * Only a relative path with no scheme or authority may contain
+   * leading `..` segments,
+   * a path that starts with `/` will also drop any leading `..` segments.
+   *
+   * This uses the same normalization strategy as `new Uri().resolve(this)`.
+   *
+   * Does not change any part of the URI except the path.
+   *
+   * The default implementation of `Uri` always normalizes paths, so calling
+   * this function has no effect.
+   */
   Uri normalizePath() {
     String path = _normalizePath(_path, scheme, hasAuthority);
     if (identical(path, _path)) return this;
@@ -1885,7 +1212,7 @@
       if (host.codeUnitAt(end - 1) != _RIGHT_BRACKET) {
         _fail(host, start, 'Missing end `]` to match `[` in host');
       }
-      Uri.parseIPv6Address(host, start + 1, end - 1);
+      parseIPv6Address(host, start + 1, end - 1);
       // RFC 5952 requires hex digits to be lower case.
       return host.substring(start, end).toLowerCase();
     }
@@ -1893,7 +1220,7 @@
       // TODO(lrn): skip if too short to be a valid IPv6 address?
       for (int i = start; i < end; i++) {
         if (host.codeUnitAt(i) == _COLON) {
-          Uri.parseIPv6Address(host, start, end);
+          parseIPv6Address(host, start, end);
           return '[$host]';
         }
       }
@@ -2006,17 +1333,6 @@
     }
     scheme = scheme.substring(start, end);
     if (containsUpperCase) scheme = scheme.toLowerCase();
-    return _canonicalizeScheme(scheme);
-  }
-
-  // Canonicalize a few often-used scheme strings.
-  //
-  // This improves memory usage and makes comparison faster.
-  static String _canonicalizeScheme(String scheme) {
-    if (scheme == "http") return "http";
-    if (scheme == "file") return "file";
-    if (scheme == "https") return "https";
-    if (scheme == "package") return "package";
     return scheme;
   }
 
@@ -2103,6 +1419,8 @@
     return _normalize(fragment, start, end, _queryCharTable);
   }
 
+  static int _stringOrNullLength(String s) => (s == null) ? 0 : s.length;
+
   /**
    * Performs RFC 3986 Percent-Encoding Normalization.
    *
@@ -2147,11 +1465,10 @@
   // Converts a UTF-16 code-unit to its value as a hex digit.
   // Returns -1 for non-hex digits.
   static int _parseHexDigit(int char) {
-    const int zeroDigit = 0x30;
-    int digit = char ^ zeroDigit;
+    int digit = char ^ Uri._ZERO;
     if (digit <= 9) return digit;
     int lowerCase = char | 0x20;
-    if (_LOWER_CASE_A <= lowerCase && lowerCase <= _LOWER_CASE_F) {
+    if (Uri._LOWER_CASE_A <= lowerCase && lowerCase <= _LOWER_CASE_F) {
       return lowerCase - (_LOWER_CASE_A - 10);
     }
     return -1;
@@ -2237,7 +1554,7 @@
             if (index + 1 < end) {
               int tail = component.codeUnitAt(index + 1);
               if ((tail & 0xFC00) == 0xDC00) {
-                // Tail surrogate.
+                // Tail surrogat.
                 sourceLength = 2;
                 char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff);
               }
@@ -2386,10 +1703,34 @@
     return output.join("/");
   }
 
+  /**
+   * Resolve [reference] as an URI relative to `this`.
+   *
+   * First turn [reference] into a URI using [Uri.parse]. Then resolve the
+   * resulting URI relative to `this`.
+   *
+   * Returns the resolved URI.
+   *
+   * See [resolveUri] for details.
+   */
   Uri resolve(String reference) {
     return resolveUri(Uri.parse(reference));
   }
 
+  /**
+   * Resolve [reference] as an URI relative to `this`.
+   *
+   * Returns the resolved URI.
+   *
+   * The algorithm "Transform Reference" for resolving a reference is described
+   * in [RFC-3986 Section 5](http://tools.ietf.org/html/rfc3986#section-5 "RFC-1123").
+   *
+   * Updated to handle the case where the base URI is just a relative path -
+   * that is: when it has no scheme or authority and the path does not start
+   * with a slash.
+   * In that case, the paths are combined without removing leading "..", and
+   * an empty path is not converted to "/".
+   */
   Uri resolveUri(Uri reference) {
     // From RFC 3986.
     String targetScheme;
@@ -2435,17 +1776,11 @@
           } else {
             // This is the RFC 3986 behavior for merging.
             if (this.hasEmptyPath) {
-              if (!this.hasAuthority) {
-                if (!this.hasScheme) {
-                  // Keep the path relative if no scheme or authority.
-                  targetPath = reference.path;
-                } else {
-                  // Remove leading dot-segments if the path is put
-                  // beneath a scheme.
-                  targetPath = _removeDotSegments(reference.path);
-                }
+              if (!this.hasScheme && !this.hasAuthority) {
+                // Keep the path relative if no scheme or authority.
+                targetPath = reference.path;
               } else {
-                // RFC algorithm for base with authority and empty path.
+                // Add path normalization on top of RFC algorithm.
                 targetPath = _removeDotSegments("/" + reference.path);
               }
             } else {
@@ -2453,9 +1788,8 @@
               if (this.hasScheme || this.hasAuthority || this.hasAbsolutePath) {
                 targetPath = _removeDotSegments(mergedPath);
               } else {
-                // Non-RFC 3986 behavior.
-                // If both base and reference are relative paths,
-                // allow the merged path to start with "..".
+                // Non-RFC 3986 beavior. If both base and reference are relative
+                // path, allow the merged path to start with "..".
                 // The RFC only specifies the case where the base has a scheme.
                 targetPath = _normalizeRelativePath(mergedPath);
               }
@@ -2466,29 +1800,63 @@
       }
     }
     String fragment = reference.hasFragment ? reference.fragment : null;
-    return new _Uri._internal(targetScheme,
-                              targetUserInfo,
-                              targetHost,
-                              targetPort,
-                              targetPath,
-                              targetQuery,
-                              fragment);
+    return new Uri._internal(targetScheme,
+                             targetUserInfo,
+                             targetHost,
+                             targetPort,
+                             targetPath,
+                             targetQuery,
+                             fragment);
   }
 
+  /**
+   * Returns whether the URI has a [scheme] component.
+   */
   bool get hasScheme => scheme.isNotEmpty;
 
+  /**
+   * Returns whether the URI has an [authority] component.
+   */
   bool get hasAuthority => _host != null;
 
+  /**
+   * Returns whether the URI has an explicit port.
+   *
+   * If the port number is the default port number
+   * (zero for unrecognized schemes, with http (80) and https (443) being
+   * recognized),
+   * then the port is made implicit and omitted from the URI.
+   */
   bool get hasPort => _port != null;
 
+  /**
+   * Returns whether the URI has a query part.
+   */
   bool get hasQuery => _query != null;
 
+  /**
+   * Returns whether the URI has a fragment part.
+   */
   bool get hasFragment => _fragment != null;
 
+  /**
+   * Returns whether the URI has an empty path.
+   */
   bool get hasEmptyPath => _path.isEmpty;
 
+  /**
+   * Returns whether the URI has an absolute path (starting with '/').
+   */
   bool get hasAbsolutePath => _path.startsWith('/');
 
+  /**
+   * Returns the origin of the URI in the form scheme://host:port for the
+   * schemes http and https.
+   *
+   * It is an error if the scheme is not "http" or "https".
+   *
+   * See: http://www.w3.org/TR/2011/WD-html5-20110405/origin-0.html#origin
+   */
   String get origin {
     if (scheme == "" || _host == null || _host == "") {
       throw new StateError("Cannot use origin without a scheme: $this");
@@ -2501,6 +1869,69 @@
     return "$scheme://$_host:$_port";
   }
 
+  /**
+   * Returns the file path from a file URI.
+   *
+   * The returned path has either Windows or non-Windows
+   * semantics.
+   *
+   * For non-Windows semantics the slash ("/") is used to separate
+   * path segments.
+   *
+   * For Windows semantics the backslash ("\") separator is used to
+   * separate path segments.
+   *
+   * If the URI is absolute the path starts with a path separator
+   * unless Windows semantics is used and the first path segment is a
+   * drive letter. When Windows semantics is used a host component in
+   * the uri in interpreted as a file server and a UNC path is
+   * returned.
+   *
+   * The default for whether to use Windows or non-Windows semantics
+   * determined from the platform Dart is running on. When running in
+   * the standalone VM this is detected by the VM based on the
+   * operating system. When running in a browser non-Windows semantics
+   * is always used.
+   *
+   * To override the automatic detection of which semantics to use pass
+   * a value for [windows]. Passing `true` will use Windows
+   * semantics and passing `false` will use non-Windows semantics.
+   *
+   * If the URI ends with a slash (i.e. the last path component is
+   * empty) the returned file path will also end with a slash.
+   *
+   * With Windows semantics URIs starting with a drive letter cannot
+   * be relative to the current drive on the designated drive. That is
+   * for the URI `file:///c:abc` calling `toFilePath` will throw as a
+   * path segment cannot contain colon on Windows.
+   *
+   * Examples using non-Windows semantics (resulting of calling
+   * toFilePath in comment):
+   *
+   *     Uri.parse("xxx/yyy");  // xxx/yyy
+   *     Uri.parse("xxx/yyy/");  // xxx/yyy/
+   *     Uri.parse("file:///xxx/yyy");  // /xxx/yyy
+   *     Uri.parse("file:///xxx/yyy/");  // /xxx/yyy/
+   *     Uri.parse("file:///C:");  // /C:
+   *     Uri.parse("file:///C:a");  // /C:a
+   *
+   * Examples using Windows semantics (resulting URI in comment):
+   *
+   *     Uri.parse("xxx/yyy");  // xxx\yyy
+   *     Uri.parse("xxx/yyy/");  // xxx\yyy\
+   *     Uri.parse("file:///xxx/yyy");  // \xxx\yyy
+   *     Uri.parse("file:///xxx/yyy/");  // \xxx\yyy/
+   *     Uri.parse("file:///C:/xxx/yyy");  // C:\xxx\yyy
+   *     Uri.parse("file:C:xxx/yyy");  // Throws as a path segment
+   *                                   // cannot contain colon on Windows.
+   *     Uri.parse("file://server/share/file");  // \\server\share\file
+   *
+   * If the URI is not a file URI calling this throws
+   * [UnsupportedError].
+   *
+   * If the URI cannot be converted to a file path calling this throws
+   * [UnsupportedError].
+   */
   String toFilePath({bool windows}) {
     if (scheme != "" && scheme != "file") {
       throw new UnsupportedError(
@@ -2515,27 +1946,25 @@
           "Cannot extract a file path from a URI with a fragment component");
     }
     if (windows == null) windows = _isWindows;
-    return windows ? _toWindowsFilePath(this) : _toFilePath();
+    return windows ? _toWindowsFilePath() : _toFilePath();
   }
 
   String _toFilePath() {
-    if (hasAuthority && host != "") {
+    if (host != "") {
       throw new UnsupportedError(
           "Cannot extract a non-Windows file path from a file URI "
           "with an authority");
     }
-    // Use path segments to have any escapes unescaped.
-    var pathSegments = this.pathSegments;
     _checkNonWindowsPathReservedCharacters(pathSegments, false);
     var result = new StringBuffer();
-    if (hasAbsolutePath) result.write("/");
+    if (_isPathAbsolute) result.write("/");
     result.writeAll(pathSegments, "/");
     return result.toString();
   }
 
-  static String _toWindowsFilePath(Uri uri) {
+  String _toWindowsFilePath() {
     bool hasDriveLetter = false;
-    var segments = uri.pathSegments;
+    var segments = pathSegments;
     if (segments.length > 0 &&
         segments[0].length == 2 &&
         segments[0].codeUnitAt(1) == _COLON) {
@@ -2543,25 +1972,23 @@
       _checkWindowsPathReservedCharacters(segments, false, 1);
       hasDriveLetter = true;
     } else {
-      _checkWindowsPathReservedCharacters(segments, false, 0);
+      _checkWindowsPathReservedCharacters(segments, false);
     }
     var result = new StringBuffer();
-    if (uri.hasAbsolutePath && !hasDriveLetter) result.write(r"\");
-    if (uri.hasAuthority) {
-      var host = uri.host;
-      if (host.isNotEmpty) {
-        result.write(r"\");
-        result.write(host);
-        result.write(r"\");
-      }
+    if (_isPathAbsolute && !hasDriveLetter) result.write("\\");
+    if (host != "") {
+      result.write("\\");
+      result.write(host);
+      result.write("\\");
     }
-    result.writeAll(segments, r"\");
-    if (hasDriveLetter && segments.length == 1) result.write(r"\");
+    result.writeAll(segments, "\\");
+    if (hasDriveLetter && segments.length == 1) result.write("\\");
     return result.toString();
   }
 
   bool get _isPathAbsolute {
-    return _path != null && _path.startsWith('/');
+    if (path == null || path.isEmpty) return false;
+    return path.startsWith('/');
   }
 
   void _writeAuthority(StringSink ss) {
@@ -2587,13 +2014,8 @@
   UriData get data => (scheme == "data") ? new UriData.fromUri(this) : null;
 
   String toString() {
-    return _text ??= _initializeText();
-  }
-
-  String _initializeText() {
-    assert(_text == null);
     StringBuffer sb = new StringBuffer();
-    if (scheme.isNotEmpty) sb..write(scheme)..write(":");
+    _addIfNonEmpty(sb, scheme, scheme, ':');
     if (hasAuthority || path.startsWith("//") || (scheme == "file")) {
       // File URIS always have the authority, even if it is empty.
       // The empty URI means "localhost".
@@ -2601,31 +2023,192 @@
       _writeAuthority(sb);
     }
     sb.write(path);
-    if (_query != null) sb..write("?")..write(_query);
-    if (_fragment != null) sb..write("#")..write(_fragment);
+    if (_query != null) { sb..write("?")..write(_query); }
+    if (_fragment != null) { sb..write("#")..write(_fragment); }
     return sb.toString();
   }
 
   bool operator==(other) {
-    if (identical(this, other)) return true;
-    if (other is Uri) {
-      Uri uri = other;
-      return scheme       == uri.scheme       &&
-             hasAuthority == uri.hasAuthority &&
-             userInfo     == uri.userInfo     &&
-             host         == uri.host         &&
-             port         == uri.port         &&
-             path         == uri.path         &&
-             hasQuery     == uri.hasQuery     &&
-             query        == uri.query        &&
-             hasFragment  == uri.hasFragment  &&
-             fragment     == uri.fragment;
-    }
-    return false;
+    if (other is! Uri) return false;
+    Uri uri = other;
+    return scheme       == uri.scheme       &&
+           hasAuthority == uri.hasAuthority &&
+           userInfo     == uri.userInfo     &&
+           host         == uri.host         &&
+           port         == uri.port         &&
+           path         == uri.path         &&
+           hasQuery     == uri.hasQuery     &&
+           query        == uri.query        &&
+           hasFragment  == uri.hasFragment  &&
+           fragment     == uri.fragment;
   }
 
   int get hashCode {
-    return _hashCodeCache ??= toString().hashCode;
+    int combine(part, current) {
+      // The sum is truncated to 30 bits to make sure it fits into a Smi.
+      return (current * 31 + part.hashCode) & 0x3FFFFFFF;
+    }
+    return combine(scheme, combine(userInfo, combine(host, combine(port,
+        combine(path, combine(query, combine(fragment, 1)))))));
+  }
+
+  static void _addIfNonEmpty(StringBuffer sb, String test,
+                             String first, String second) {
+    if ("" != test) {
+      sb.write(first);
+      sb.write(second);
+    }
+  }
+
+  /**
+   * Encode the string [component] using percent-encoding to make it
+   * safe for literal use as a URI component.
+   *
+   * All characters except uppercase and lowercase letters, digits and
+   * the characters `-_.!~*'()` are percent-encoded. This is the
+   * set of characters specified in RFC 2396 and the which is
+   * specified for the encodeUriComponent in ECMA-262 version 5.1.
+   *
+   * When manually encoding path segments or query components remember
+   * to encode each part separately before building the path or query
+   * string.
+   *
+   * For encoding the query part consider using
+   * [encodeQueryComponent].
+   *
+   * To avoid the need for explicitly encoding use the [pathSegments]
+   * and [queryParameters] optional named arguments when constructing
+   * a [Uri].
+   */
+  static String encodeComponent(String component) {
+    return _uriEncode(_unreserved2396Table, component, UTF8, false);
+  }
+
+  /**
+   * Encode the string [component] according to the HTML 4.01 rules
+   * for encoding the posting of a HTML form as a query string
+   * component.
+   *
+   * Encode the string [component] according to the HTML 4.01 rules
+   * for encoding the posting of a HTML form as a query string
+   * component.
+
+   * The component is first encoded to bytes using [encoding].
+   * The default is to use [UTF8] encoding, which preserves all
+   * the characters that don't need encoding.
+
+   * Then the resulting bytes are "percent-encoded". This transforms
+   * spaces (U+0020) to a plus sign ('+') and all bytes that are not
+   * the ASCII decimal digits, letters or one of '-._~' are written as
+   * a percent sign '%' followed by the two-digit hexadecimal
+   * representation of the byte.
+
+   * Note that the set of characters which are percent-encoded is a
+   * superset of what HTML 4.01 requires, since it refers to RFC 1738
+   * for reserved characters.
+   *
+   * When manually encoding query components remember to encode each
+   * part separately before building the query string.
+   *
+   * To avoid the need for explicitly encoding the query use the
+   * [queryParameters] optional named arguments when constructing a
+   * [Uri].
+   *
+   * See http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 for more
+   * details.
+   */
+  static String encodeQueryComponent(String component,
+                                     {Encoding encoding: UTF8}) {
+    return _uriEncode(_unreservedTable, component, encoding, true);
+  }
+
+  /**
+   * Decodes the percent-encoding in [encodedComponent].
+   *
+   * Note that decoding a URI component might change its meaning as
+   * some of the decoded characters could be characters with are
+   * delimiters for a given URI componene type. Always split a URI
+   * component using the delimiters for the component before decoding
+   * the individual parts.
+   *
+   * For handling the [path] and [query] components consider using
+   * [pathSegments] and [queryParameters] to get the separated and
+   * decoded component.
+   */
+  static String decodeComponent(String encodedComponent) {
+    return _uriDecode(encodedComponent, 0, encodedComponent.length,
+                      UTF8, false);
+  }
+
+  /**
+   * Decodes the percent-encoding in [encodedComponent], converting
+   * pluses to spaces.
+   *
+   * It will create a byte-list of the decoded characters, and then use
+   * [encoding] to decode the byte-list to a String. The default encoding is
+   * UTF-8.
+   */
+  static String decodeQueryComponent(
+      String encodedComponent,
+      {Encoding encoding: UTF8}) {
+    return _uriDecode(encodedComponent, 0, encodedComponent.length,
+                      encoding, true);
+  }
+
+  /**
+   * Encode the string [uri] using percent-encoding to make it
+   * safe for literal use as a full URI.
+   *
+   * All characters except uppercase and lowercase letters, digits and
+   * the characters `!#$&'()*+,-./:;=?@_~` are percent-encoded. This
+   * is the set of characters specified in in ECMA-262 version 5.1 for
+   * the encodeURI function .
+   */
+  static String encodeFull(String uri) {
+    return _uriEncode(_encodeFullTable, uri, UTF8, false);
+  }
+
+  /**
+   * Decodes the percent-encoding in [uri].
+   *
+   * Note that decoding a full URI might change its meaning as some of
+   * the decoded characters could be reserved characters. In most
+   * cases an encoded URI should be parsed into components using
+   * [Uri.parse] before decoding the separate components.
+   */
+  static String decodeFull(String uri) {
+    return _uriDecode(uri, 0, uri.length, UTF8, false);
+  }
+
+  /**
+   * Returns the [query] split into a map according to the rules
+   * specified for FORM post in the [HTML 4.01 specification section
+   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
+   * Each key and value in the returned map has been decoded. If the [query]
+   * is the empty string an empty map is returned.
+   *
+   * Keys in the query string that have no value are mapped to the
+   * empty string.
+   *
+   * Each query component will be decoded using [encoding]. The default encoding
+   * is UTF-8.
+   */
+  static Map<String, String> splitQueryString(String query,
+                                              {Encoding encoding: UTF8}) {
+    return query.split("&").fold({}, (map, element) {
+      int index = element.indexOf("=");
+      if (index == -1) {
+        if (element != "") {
+          map[decodeQueryComponent(element, encoding: encoding)] = "";
+        }
+      } else if (index != 0) {
+        var key = element.substring(0, index);
+        var value = element.substring(index + 1);
+        map[Uri.decodeQueryComponent(key, encoding: encoding)] =
+            decodeQueryComponent(value, encoding: encoding);
+      }
+      return map;
+    });
   }
 
   static List _createList() => [];
@@ -2668,6 +2251,175 @@
     return result;
   }
 
+  /**
+   * Parse the [host] as an IP version 4 (IPv4) address, returning the address
+   * as a list of 4 bytes in network byte order (big endian).
+   *
+   * Throws a [FormatException] if [host] is not a valid IPv4 address
+   * representation.
+   */
+  static List<int> parseIPv4Address(String host) {
+    void error(String msg) {
+      throw new FormatException('Illegal IPv4 address, $msg');
+    }
+    var bytes = host.split('.');
+    if (bytes.length != 4) {
+      error('IPv4 address should contain exactly 4 parts');
+    }
+    // TODO(ajohnsen): Consider using Uint8List.
+    return bytes
+        .map((byteString) {
+          int byte = int.parse(byteString);
+          if (byte < 0 || byte > 255) {
+            error('each part must be in the range of `0..255`');
+          }
+          return byte;
+        })
+        .toList();
+  }
+
+  /**
+   * Parse the [host] as an IP version 6 (IPv6) address, returning the address
+   * as a list of 16 bytes in network byte order (big endian).
+   *
+   * Throws a [FormatException] if [host] is not a valid IPv6 address
+   * representation.
+   *
+   * Acts on the substring from [start] to [end]. If [end] is omitted, it
+   * defaults ot the end of the string.
+   *
+   * Some examples of IPv6 addresses:
+   *  * ::1
+   *  * FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
+   *  * 3ffe:2a00:100:7031::1
+   *  * ::FFFF:129.144.52.38
+   *  * 2010:836B:4179::836B:4179
+   */
+  static List<int> parseIPv6Address(String host, [int start = 0, int end]) {
+    if (end == null) end = host.length;
+    // An IPv6 address consists of exactly 8 parts of 1-4 hex digits, seperated
+    // by `:`'s, with the following exceptions:
+    //
+    //  - One (and only one) wildcard (`::`) may be present, representing a fill
+    //    of 0's. The IPv6 `::` is thus 16 bytes of `0`.
+    //  - The last two parts may be replaced by an IPv4 address.
+    void error(String msg, [position]) {
+      throw new FormatException('Illegal IPv6 address, $msg', host, position);
+    }
+    int parseHex(int start, int end) {
+      if (end - start > 4) {
+        error('an IPv6 part can only contain a maximum of 4 hex digits', start);
+      }
+      int value = int.parse(host.substring(start, end), radix: 16);
+      if (value < 0 || value > (1 << 16) - 1) {
+        error('each part must be in the range of `0x0..0xFFFF`', start);
+      }
+      return value;
+    }
+    if (host.length < 2) error('address is too short');
+    List<int> parts = [];
+    bool wildcardSeen = false;
+    int partStart = start;
+    // Parse all parts, except a potential last one.
+    for (int i = start; i < end; i++) {
+      if (host.codeUnitAt(i) == _COLON) {
+        if (i == start) {
+          // If we see a `:` in the beginning, expect wildcard.
+          i++;
+          if (host.codeUnitAt(i) != _COLON) {
+            error('invalid start colon.', i);
+          }
+          partStart = i;
+        }
+        if (i == partStart) {
+          // Wildcard. We only allow one.
+          if (wildcardSeen) {
+            error('only one wildcard `::` is allowed', i);
+          }
+          wildcardSeen = true;
+          parts.add(-1);
+        } else {
+          // Found a single colon. Parse [partStart..i] as a hex entry.
+          parts.add(parseHex(partStart, i));
+        }
+        partStart = i + 1;
+      }
+    }
+    if (parts.length == 0) error('too few parts');
+    bool atEnd = (partStart == end);
+    bool isLastWildcard = (parts.last == -1);
+    if (atEnd && !isLastWildcard) {
+      error('expected a part after last `:`', end);
+    }
+    if (!atEnd) {
+      try {
+        parts.add(parseHex(partStart, end));
+      } catch (e) {
+        // Failed to parse the last chunk as hex. Try IPv4.
+        try {
+          List<int> last = parseIPv4Address(host.substring(partStart, end));
+          parts.add(last[0] << 8 | last[1]);
+          parts.add(last[2] << 8 | last[3]);
+        } catch (e) {
+          error('invalid end of IPv6 address.', partStart);
+        }
+      }
+    }
+    if (wildcardSeen) {
+      if (parts.length > 7) {
+        error('an address with a wildcard must have less than 7 parts');
+      }
+    } else if (parts.length != 8) {
+      error('an address without a wildcard must contain exactly 8 parts');
+    }
+    List<int> bytes = new Uint8List(16);
+    for (int i = 0, index = 0; i < parts.length; i++) {
+      int value = parts[i];
+      if (value == -1) {
+        int wildCardLength = 9 - parts.length;
+        for (int j = 0; j < wildCardLength; j++) {
+          bytes[index] = 0;
+          bytes[index + 1] = 0;
+          index += 2;
+        }
+      } else {
+        bytes[index] = value >> 8;
+        bytes[index + 1] = value & 0xff;
+        index += 2;
+      }
+    }
+    return bytes;
+  }
+
+  // Frequently used character codes.
+  static const int _SPACE = 0x20;
+  static const int _DOUBLE_QUOTE = 0x22;
+  static const int _NUMBER_SIGN = 0x23;
+  static const int _PERCENT = 0x25;
+  static const int _ASTERISK = 0x2A;
+  static const int _PLUS = 0x2B;
+  static const int _DOT = 0x2E;
+  static const int _SLASH = 0x2F;
+  static const int _ZERO = 0x30;
+  static const int _NINE = 0x39;
+  static const int _COLON = 0x3A;
+  static const int _LESS = 0x3C;
+  static const int _GREATER = 0x3E;
+  static const int _QUESTION = 0x3F;
+  static const int _AT_SIGN = 0x40;
+  static const int _UPPER_CASE_A = 0x41;
+  static const int _UPPER_CASE_F = 0x46;
+  static const int _UPPER_CASE_Z = 0x5A;
+  static const int _LEFT_BRACKET = 0x5B;
+  static const int _BACKSLASH = 0x5C;
+  static const int _RIGHT_BRACKET = 0x5D;
+  static const int _LOWER_CASE_A = 0x61;
+  static const int _LOWER_CASE_F = 0x66;
+  static const int _LOWER_CASE_Z = 0x7A;
+  static const int _BAR = 0x7C;
+
+  static const String _hexDigits = "0123456789ABCDEF";
+
   external static String _uriEncode(List<int> canonicalTable,
                                     String text,
                                     Encoding encoding,
@@ -3189,13 +2941,13 @@
         throw new ArgumentError.value(mimeType, "mimeType",
                                       "Invalid MIME type");
       }
-      buffer.write(_Uri._uriEncode(_tokenCharTable,
-                                   mimeType.substring(0, slashIndex),
-                                   UTF8, false));
+      buffer.write(Uri._uriEncode(_tokenCharTable,
+                                  mimeType.substring(0, slashIndex),
+                                  UTF8, false));
       buffer.write("/");
-      buffer.write(_Uri._uriEncode(_tokenCharTable,
-                                   mimeType.substring(slashIndex + 1),
-                                   UTF8, false));
+      buffer.write(Uri._uriEncode(_tokenCharTable,
+                                  mimeType.substring(slashIndex + 1),
+                                  UTF8, false));
     }
     if (charsetName != null) {
       if (indices != null) {
@@ -3203,7 +2955,7 @@
                ..add(buffer.length + 8);
       }
       buffer.write(";charset=");
-      buffer.write(_Uri._uriEncode(_tokenCharTable, charsetName, UTF8, false));
+      buffer.write(Uri._uriEncode(_tokenCharTable, charsetName, UTF8, false));
     }
     parameters?.forEach((var key, var value) {
       if (key.isEmpty) {
@@ -3216,10 +2968,10 @@
       if (indices != null) indices.add(buffer.length);
       buffer.write(';');
       // Encode any non-RFC2045-token character and both '%' and '#'.
-      buffer.write(_Uri._uriEncode(_tokenCharTable, key, UTF8, false));
+      buffer.write(Uri._uriEncode(_tokenCharTable, key, UTF8, false));
       if (indices != null) indices.add(buffer.length);
       buffer.write('=');
-      buffer.write(_Uri._uriEncode(_tokenCharTable, value, UTF8, false));
+      buffer.write(Uri._uriEncode(_tokenCharTable, value, UTF8, false));
     });
   }
 
@@ -3236,7 +2988,7 @@
     int slashIndex = -1;
     for (int i = 0; i < mimeType.length; i++) {
       var char = mimeType.codeUnitAt(i);
-      if (char != _SLASH) continue;
+      if (char != Uri._SLASH) continue;
       if (slashIndex < 0) {
         slashIndex = i;
         continue;
@@ -3256,7 +3008,7 @@
    * ````
    *
    * where `type`, `subtype`, `attribute` and `value` are specified in RFC-2045,
-   * and `data` is a sequence of URI-characters (RFC-2396 `uric`).
+   * and `data` is a sequnce of URI-characters (RFC-2396 `uric`).
    *
    * This means that all the characters must be ASCII, but the URI may contain
    * percent-escapes for non-ASCII byte values that need an interpretation
@@ -3267,22 +3019,13 @@
    * and `,` delimiters.
    *
    * Accessing the individual parts may fail later if they turn out to have
-   * content that can't be decoded successfully as a string.
+   * content that can't be decoded sucessfully as a string.
    */
   static UriData parse(String uri) {
-    if (uri.length >= 5) {
-      int dataDelta = _startsWithData(uri, 0);
-      if (dataDelta == 0) {
-        // Exact match on "data:".
-        return _parse(uri, 5, null);
-      }
-      if (dataDelta == 0x20) {
-        // Starts with a non-normalized "data" scheme containing upper-case
-        // letters. Parse anyway, but throw away the scheme.
-        return _parse(uri.substring(5), 0, null);
-      }
+    if (!uri.startsWith("data:")) {
+      throw new FormatException("Does not start with 'data:'", uri, 0);
     }
-    throw new FormatException("Does not start with 'data:'", uri, 0);
+    return _parse(uri, 5, null);
   }
 
   /**
@@ -3307,7 +3050,7 @@
     // That's perfectly reasonable - data URIs are not hierarchical,
     // but it may make some consumers stumble.
     // Should we at least do escape normalization?
-    _uriCache = new _Uri._internal("data", "", null, null, path, query, null);
+    _uriCache = new Uri._internal("data", "", null, null, path, query, null);
     return _uriCache;
   }
 
@@ -3332,7 +3075,7 @@
     int start = _separatorIndices[0] + 1;
     int end = _separatorIndices[1];
     if (start == end) return "text/plain";
-    return _Uri._uriDecode(_text, start, end, UTF8, false);
+    return Uri._uriDecode(_text, start, end, UTF8, false);
   }
 
   /**
@@ -3353,8 +3096,8 @@
       var keyStart = _separatorIndices[i] + 1;
       var keyEnd = _separatorIndices[i + 1];
       if (keyEnd == keyStart + 7 && _text.startsWith("charset", keyStart)) {
-        return _Uri._uriDecode(_text, keyEnd + 1, _separatorIndices[i + 2],
-                               UTF8, false);
+        return Uri._uriDecode(_text, keyEnd + 1, _separatorIndices[i + 2],
+                              UTF8, false);
       }
     }
     return "US-ASCII";
@@ -3412,8 +3155,8 @@
         result[index++] = codeUnit;
       } else {
         if (i + 2 < text.length) {
-          var digit1 = _Uri._parseHexDigit(text.codeUnitAt(i + 1));
-          var digit2 = _Uri._parseHexDigit(text.codeUnitAt(i + 2));
+          var digit1 = Uri._parseHexDigit(text.codeUnitAt(i + 1));
+          var digit2 = Uri._parseHexDigit(text.codeUnitAt(i + 2));
           if (digit1 >= 0 && digit2 >= 0) {
             int byte = digit1 * 16 + digit2;
             result[index++] = byte;
@@ -3434,7 +3177,7 @@
    * If the content is Base64 encoded, it will be decoded to bytes and then
    * decoded to a string using [encoding].
    * If encoding is omitted, the value of a `charset` parameter is used
-   * if it is recognized by [Encoding.getByName], otherwise it defaults to
+   * if it is recongized by [Encoding.getByName], otherwise it defaults to
    * the [ASCII] encoding, which is the default encoding for data URIs
    * that do not specify an encoding.
    *
@@ -3456,7 +3199,7 @@
       var converter = BASE64.decoder.fuse(encoding.decoder);
       return converter.convert(text.substring(start));
     }
-    return _Uri._uriDecode(text, start, text.length, encoding, false);
+    return Uri._uriDecode(text, start, text.length, encoding, false);
   }
 
   /**
@@ -3479,8 +3222,8 @@
       var start = _separatorIndices[i - 2] + 1;
       var equals = _separatorIndices[i - 1];
       var end = _separatorIndices[i];
-      String key = _Uri._uriDecode(_text, start, equals, UTF8, false);
-      String value = _Uri._uriDecode(_text,equals + 1, end, UTF8, false);
+      String key = Uri._uriDecode(_text, start, equals, UTF8, false);
+      String value = Uri._uriDecode(_text,equals + 1, end, UTF8, false);
       result[key] = value;
     }
     return result;
@@ -3563,9 +3306,9 @@
           ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
         buffer.writeCharCode(byte);
       } else {
-        buffer.writeCharCode(_PERCENT);
-        buffer.writeCharCode(_hexDigits.codeUnitAt(byte >> 4));
-        buffer.writeCharCode(_hexDigits.codeUnitAt(byte & 0x0f));
+        buffer.writeCharCode(Uri._PERCENT);
+        buffer.writeCharCode(Uri._hexDigits.codeUnitAt(byte >> 4));
+        buffer.writeCharCode(Uri._hexDigits.codeUnitAt(byte & 0x0f));
       }
     }
     if ((byteOr & ~0xFF) != 0) {
@@ -3614,852 +3357,5 @@
   //  mark        =  "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
   //
   // This is the same characters as in a URI query (which is URI pchar plus '?')
-  static const _uricTable = _Uri._queryCharTable;
+  static const _uricTable = Uri._queryCharTable;
 }
-
-// --------------------------------------------------------------------
-// Constants used to read the scanner result.
-// The indices points into the table filled by [_scan] which contains
-// recognized positions in the scanned URI.
-// The `0` index is only used internally.
-
-/// Index of the position of that `:` after a scheme.
-const int _schemeEndIndex     = 1;
-/// Index of the position of the character just before the host name.
-const int _hostStartIndex     = 2;
-/// Index of the position of the `:` before a port value.
-const int _portStartIndex     = 3;
-/// Index of the position of the first character of a path.
-const int _pathStartIndex     = 4;
-/// Index of the position of the `?` before a query.
-const int _queryStartIndex    = 5;
-/// Index of the position of the `#` before a fragment.
-const int _fragmentStartIndex = 6;
-/// Index of a position where the URI was determined to be "non-simple".
-const int _notSimpleIndex     = 7;
-
-// Initial state for scanner.
-const int _uriStart           = 00;
-
-// If scanning of a URI terminates in this state or above,
-// consider the URI non-simple
-const int _nonSimpleEndStates = 14;
-
-// Initial state for scheme validation.
-const int _schemeStart        = 20;
-
-/// Transition tables used to scan a URI to determine its structure.
-///
-/// The tables represent a state machine with output.
-///
-/// To scan the URI, start in the [_uriStart] state, then read each character
-/// of the URI in order, from start to end, and for each character perform a
-/// transition to a new state while writing the current position into the output
-/// buffer at a designated index.
-///
-/// Each state, represented by an integer which is an index into
-/// [_scannerTables], has a set of transitions, one for each character.
-/// The transitions are encoded as a 5-bit integer representing the next state
-/// and a 3-bit index into the output table.
-///
-/// For URI scanning, only characters in the range U+0020 through U+007E are
-/// interesting, all characters outside that range are treated the same.
-/// The tables only contain 96 entries, representing that characters in the
-/// interesting range, plus one more to represent all values outside the range.
-/// The character entries are stored in one `Uint8List` per state, with the
-/// transition for a character at position `character ^ 0x60`,
-/// which maps the range U+0020 .. U+007F into positions 0 .. 95.
-/// All remaining characters are mapped to position 31 (`0x7f ^ 0x60`) which
-/// represents the transition for all remaining characters.
-final List<Uint8List> _scannerTables = _createTables();
-
-// ----------------------------------------------------------------------
-// Code to create the URI scanner table.
-
-/// Creates the tables for [_scannerTables] used by [Uri.parse].
-///
-/// See [_scannerTables] for the generated format.
-///
-/// The concrete tables are chosen as a trade-off between the number of states
-/// needed and the precision of the result.
-/// This allows definitely recognizing the general structure of the URI
-/// (presence and location of scheme, user-info, host, port, path, query and
-/// fragment) while at the same time detecting that some components are not
-/// in canonical form (anything containing a `%`, a host-name containing a
-/// capital letter). Since the scanner doesn't know whether something is a
-/// scheme or a path until it sees `:`, or user-info or host until it sees
-/// a `@`, a second pass is needed to validate the scheme and any user-info
-/// is considered non-canonical by default.
-///
-/// The states (starting from [_uriStart]) write positions while scanning
-/// a string from `start` to `end` as follows:
-///
-/// - [_schemeEndIndex]: Should be initialized to `start-1`.
-///   If the URI has a scheme, it is set to the position of the `:` after
-///   the scheme.
-/// - [_hostStartIndex]: Should be initialized to `start - 1`.
-///   If the URI has an authority, it is set to the character before the
-///   host name - either the second `/` in the `//` leading the authority,
-///   or the `@` after a user-info. Comparing this value to the scheme end
-///   position can be used to detect that there is a user-info component.
-/// - [_portStartIndex]: Should be initialized to `start`.
-///   Set to the position of the last `:` in an authority, and unchanged
-///   if there is no authority or no `:` in an authority.
-///   If this position is after the host start, there is a port, otherwise it
-///   is just marking a colon in the user-info component.
-/// - [_pathStartIndex]: Should be initialized to `start`.
-///   Is set to the first path character unless the path is empty.
-///   If the path is empty, the position is either unchanged (`start`) or
-///   the first slash of an authority. So, if the path start is before a
-///   host start or scheme end, the path is empty.
-/// - [_queryStartIndex]: Should be initialized to `end`.
-///   The position of the `?` leading a query if the URI contains a query.
-/// - [_fragmentStartIndex]: Should be initialized to `end`.
-///   The position of the `#` leading a fragment if the URI contains a fragment.
-/// - [_notSimpleIndex]: Should be initialized to `start - 1`.
-///   Set to another value if the URI is considered "not simple".
-///   This is elaborated below.
-///
-/// # Simple URIs
-/// A URI is considered "simple" if it is in a normalized form containing no
-/// escapes. This allows us to skip normalization and checking whether escapes
-/// are valid, and to extract components without worrying about unescaping.
-///
-/// The scanner computes a conservative approximation of being "simple".
-/// It rejects any URI with an escape, with a user-info component (mainly
-/// because they are rare and would increase the number of states in the
-/// scanner significantly), with an IPV6 host or with a capital letter in
-/// the scheme or host name (the scheme is handled in a second scan using
-/// a separate two-state table).
-/// Further, paths containing `..` or `.` path segments are considered
-/// non-simple except for pure relative paths (no scheme or authority) starting
-/// with a sequence of "../" segments.
-///
-/// The transition tables cannot detect a trailing ".." in the path,
-/// followed by a query or fragment, because the segment is not known to be
-/// complete until we are past it, and we then need to store the query/fragment
-/// start instead. This cast is checked manually post-scanning (such a path
-/// needs to be normalized to end in "../", so the URI shouldn't be considered
-/// simple).
-List<Uint8List> _createTables() {
-  // TODO(lrn): Use a precomputed table.
-
-  // Total number of states for the scanner.
-  const int stateCount         = 22;
-
-  // States used to scan a URI from scratch.
-  const int schemeOrPath       = 01;
-  const int authOrPath         = 02;
-  const int authOrPathSlash    = 03;
-  const int uinfoOrHost0       = 04;
-  const int uinfoOrHost        = 05;
-  const int uinfoOrPort0       = 06;
-  const int uinfoOrPort        = 07;
-  const int ipv6Host           = 08;
-  const int relPathSeg         = 09;
-  const int pathSeg            = 10;
-  const int path               = 11;
-  const int query              = 12;
-  const int fragment           = 13;
-  const int schemeOrPathDot    = 14;
-  const int schemeOrPathDot2   = 15;
-  const int relPathSegDot      = 16;
-  const int relPathSegDot2     = 17;
-  const int pathSegDot         = 18;
-  const int pathSegDot2        = 19;
-
-  // States used to validate a scheme after its end position has been found.
-  const int scheme0            = _schemeStart;
-  const int scheme             = 21;
-
-  // Constants encoding the write-index for the state transition into the top 5
-  // bits of a byte.
-  const int schemeEnd          = _schemeEndIndex     << 5;
-  const int hostStart          = _hostStartIndex     << 5;
-  const int portStart          = _portStartIndex     << 5;
-  const int pathStart          = _pathStartIndex     << 5;
-  const int queryStart         = _queryStartIndex    << 5;
-  const int fragmentStart      = _fragmentStartIndex << 5;
-  const int notSimple          = _notSimpleIndex     << 5;
-
-  /// The `unreserved` characters of RFC 3986.
-  const unreserved =
-      "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~"  ;
-  /// The `sub-delim` characters of RFC 3986.
-  const subDelims = r"!$&'()*+,;=";
-  // The `pchar` characters of RFC 3986: characters that may occur in a path,
-  // excluding escapes.
-  const pchar = "$unreserved$subDelims";
-
-  var tables = new List<Uint8List>.generate(stateCount,
-      (_) => new Uint8List(96));
-
-  // Helper function which initialize the table for [state] with a default
-  // transition and returns the table.
-  Uint8List build(state, defaultTransition) =>
-      tables[state]..fillRange(0, 96, defaultTransition);
-
-  // Helper function which sets the transition for each character in [chars]
-  // to [transition] in the [target] table.
-  // The [chars] string must contain only characters in the U+0020 .. U+007E
-  // range.
-  void setChars(Uint8List target, String chars, int transition) {
-    for (int i = 0; i < chars.length; i++) {
-      var char = chars.codeUnitAt(i);
-      target[char ^ 0x60] = transition;
-    }
-  }
-
-  /// Helper function which sets the transition for all characters in the
-  /// range from `range[0]` to `range[1]` to [transition] in the [target] table.
-  ///
-  /// The [range] must be a two-character string where both characters are in
-  /// the U+0020 .. U+007E range and the former character must have a lower
-  /// code point than the latter.
-  void setRange(Uint8List target, String range, int transition) {
-    for (int i = range.codeUnitAt(0), n = range.codeUnitAt(1); i <= n; i++) {
-      target[i ^ 0x60] = transition;
-    }
-  }
-
-  // Create the transitions for each state.
-  var b;
-
-  // Validate as path, if it is a scheme, we handle it later.
-  b = build(_uriStart, schemeOrPath | notSimple);
-  setChars(b, pchar, schemeOrPath);
-  setChars(b, ".", schemeOrPathDot);
-  setChars(b, ":", authOrPath | schemeEnd);  // Handle later.
-  setChars(b, "/", authOrPathSlash);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(schemeOrPathDot, schemeOrPath | notSimple);
-  setChars(b, pchar, schemeOrPath);
-  setChars(b, ".", schemeOrPathDot2);
-  setChars(b, ':', authOrPath | schemeEnd);
-  setChars(b, "/", pathSeg | notSimple);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(schemeOrPathDot2, schemeOrPath | notSimple);
-  setChars(b, pchar, schemeOrPath);
-  setChars(b, "%", schemeOrPath | notSimple);
-  setChars(b, ':', authOrPath | schemeEnd);
-  setChars(b, "/", relPathSeg);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(schemeOrPath, schemeOrPath | notSimple);
-  setChars(b, pchar, schemeOrPath);
-  setChars(b, ':', authOrPath | schemeEnd);
-  setChars(b, "/", pathSeg);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(authOrPath, path | notSimple);
-  setChars(b, pchar, path | pathStart);
-  setChars(b, "/", authOrPathSlash | pathStart);
-  setChars(b, ".", pathSegDot | pathStart);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(authOrPathSlash, path | notSimple);
-  setChars(b, pchar, path);
-  setChars(b, "/", uinfoOrHost0 | hostStart);
-  setChars(b, ".", pathSegDot);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(uinfoOrHost0, uinfoOrHost | notSimple);
-  setChars(b, pchar, uinfoOrHost);
-  setRange(b, "AZ", uinfoOrHost | notSimple);
-  setChars(b, ":", uinfoOrPort0 | portStart);
-  setChars(b, "@", uinfoOrHost0 | hostStart);
-  setChars(b, "[", ipv6Host | notSimple);
-  setChars(b, "/", pathSeg | pathStart);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(uinfoOrHost, uinfoOrHost | notSimple);
-  setChars(b, pchar, uinfoOrHost);
-  setRange(b, "AZ", uinfoOrHost | notSimple);
-  setChars(b, ":", uinfoOrPort0 | portStart);
-  setChars(b, "@", uinfoOrHost0 | hostStart);
-  setChars(b, "/", pathSeg | pathStart);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(uinfoOrPort0, uinfoOrPort | notSimple);
-  setRange(b, "19", uinfoOrPort);
-  setChars(b, "@", uinfoOrHost0 | hostStart);
-  setChars(b, "/", pathSeg | pathStart);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(uinfoOrPort, uinfoOrPort | notSimple);
-  setRange(b, "09", uinfoOrPort);
-  setChars(b, "@", uinfoOrHost0 | hostStart);
-  setChars(b, "/", pathSeg | pathStart);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(ipv6Host, ipv6Host);
-  setChars(b, "]", uinfoOrHost);
-
-  b = build(relPathSeg, path | notSimple);
-  setChars(b, pchar, path);
-  setChars(b, ".", relPathSegDot);
-  setChars(b, "/", pathSeg | notSimple);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(relPathSegDot, path | notSimple);
-  setChars(b, pchar, path);
-  setChars(b, ".", relPathSegDot2);
-  setChars(b, "/", pathSeg | notSimple);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(relPathSegDot2, path | notSimple);
-  setChars(b, pchar, path);
-  setChars(b, "/", relPathSeg);
-  setChars(b, "?", query | queryStart);  // This should be non-simple.
-  setChars(b, "#", fragment | fragmentStart);  // This should be non-simple.
-
-  b = build(pathSeg, path | notSimple);
-  setChars(b, pchar, path);
-  setChars(b, ".", pathSegDot);
-  setChars(b, "/", pathSeg | notSimple);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(pathSegDot, path | notSimple);
-  setChars(b, pchar, path);
-  setChars(b, ".", pathSegDot2);
-  setChars(b, "/", pathSeg | notSimple);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(pathSegDot2, path | notSimple);
-  setChars(b, pchar, path);
-  setChars(b, "/", pathSeg | notSimple);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(path, path | notSimple);
-  setChars(b, pchar, path);
-  setChars(b, "/", pathSeg);
-  setChars(b, "?", query | queryStart);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(query, query | notSimple);
-  setChars(b, pchar, query);
-  setChars(b, "?", query);
-  setChars(b, "#", fragment | fragmentStart);
-
-  b = build(fragment, fragment | notSimple);
-  setChars(b, pchar, fragment);
-  setChars(b, "?", fragment);
-
-  // A separate two-state validator for lower-case scheme names.
-  // Any non-scheme character or upper-case letter is marked as non-simple.
-  b = build(scheme0, scheme | notSimple);
-  setRange(b, "az", scheme);
-
-  b = build(scheme, scheme | notSimple);
-  setRange(b, "az", scheme);
-  setRange(b, "09", scheme);
-  setChars(b, "+-.", scheme);
-
-  return tables;
-}
-
-// --------------------------------------------------------------------
-// Code that uses the URI scanner table.
-
-/// Scan a string using the [_scannerTables] state machine.
-///
-/// Scans [uri] from [start] to [end], startig in state [state] and
-/// writing output into [indices].
-///
-/// Returns the final state.
-int _scan(String uri, int start, int end, int state, List<int> indices) {
-  var tables = _scannerTables;
-  assert(end <= uri.length);
-  for (int i = start; i < end; i++) {
-    var table = tables[state];
-    // Xor with 0x60 to move range 0x20-0x7f into 0x00-0x5f
-    int char = uri.codeUnitAt(i) ^ 0x60;
-    // Use 0x1f (nee 0x7f) to represent all unhandled characters.
-    if (char > 0x5f) char = 0x1f;
-    int transition = table[char];
-    state = transition & 0x1f;
-    indices[transition >> 5] = i;
-  }
-  return state;
-}
-
-class _SimpleUri implements Uri {
-  final String _uri;
-  final int _schemeEnd;
-  final int _hostStart;
-  final int _portStart;
-  final int _pathStart;
-  final int _queryStart;
-  final int _fragmentStart;
-  /// The scheme is often used to distinguish URIs.
-  /// To make comparisons more efficient, we cache the value, and
-  /// canonicalize a few known types.
-  String _schemeCache;
-  int _hashCodeCache;
-
-  _SimpleUri(
-      this._uri,
-      this._schemeEnd,
-      this._hostStart,
-      this._portStart,
-      this._pathStart,
-      this._queryStart,
-      this._fragmentStart,
-      this._schemeCache);
-
-  bool get hasScheme => _schemeEnd > 0;
-  bool get hasAuthority => _hostStart > 0;
-  bool get hasUserInfo => _hostStart > _schemeEnd + 4;
-  bool get hasPort => _hostStart > 0 && _portStart + 1 < _pathStart;
-  bool get hasQuery => _queryStart < _fragmentStart;
-  bool get hasFragment => _fragmentStart < _uri.length;
-
-  bool get _isFile => _schemeEnd == 4 && _uri.startsWith("file");
-  bool get _isHttp => _schemeEnd == 4 && _uri.startsWith("http");
-  bool get _isHttps => _schemeEnd == 5 && _uri.startsWith("https");
-  bool get _isPackage => _schemeEnd == 7 && _uri.startsWith("package");
-  bool _isScheme(String scheme) =>
-    _schemeEnd == scheme.length && _uri.startsWith(scheme);
-
-  bool get hasAbsolutePath => _uri.startsWith("/", _pathStart);
-  bool get hasEmptyPath => _pathStart == _queryStart;
-
-  bool get isAbsolute => hasScheme && !hasFragment;
-
-  String get scheme {
-    if (_schemeEnd <= 0) return "";
-    if (_schemeCache != null) return _schemeCache;
-    if (_isHttp) {
-      _schemeCache = "http";
-    } else if (_isHttps) {
-      _schemeCache = "https";
-    } else if (_isFile) {
-      _schemeCache = "file";
-    } else if (_isPackage) {
-      _schemeCache = "package";
-    } else {
-      _schemeCache = _uri.substring(0, _schemeEnd);
-    }
-    return _schemeCache;
-  }
-  String get authority => _hostStart > 0 ?
-      _uri.substring(_schemeEnd + 3, _pathStart) : "";
-  String get userInfo => (_hostStart > _schemeEnd + 3) ?
-      _uri.substring(_schemeEnd + 3, _hostStart - 1) : "";
-  String get host =>
-      _hostStart > 0 ? _uri.substring(_hostStart, _portStart) : "";
-  int get port {
-    if (hasPort) return int.parse(_uri.substring(_portStart + 1, _pathStart));
-    if (_isHttp) return 80;
-    if (_isHttps) return 443;
-    return 0;
-  }
-  String get path =>_uri.substring(_pathStart, _queryStart);
-  String get query => (_queryStart < _fragmentStart) ?
-     _uri.substring(_queryStart + 1, _fragmentStart) : "";
-  String get fragment => (_fragmentStart < _uri.length) ?
-     _uri.substring(_fragmentStart + 1) : "";
-
-  String get origin {
-    // Check original behavior - W3C spec is wonky!
-    bool isHttp = _isHttp;
-    if (_schemeEnd < 0 || _hostStart == _portStart) {
-      throw new StateError("Cannot use origin without a scheme: $this");
-    }
-    if (!isHttp && !_isHttps) {
-      throw new StateError(
-        "Origin is only applicable schemes http and https: $this");
-    }
-    if (_hostStart == _schemeEnd + 3) {
-      return _uri.substring(0, _pathStart);
-    }
-    // Need to drop anon-empty userInfo.
-    return _uri.substring(0, _schemeEnd + 3) +
-           _uri.substring(_hostStart, _pathStart);
-  }
-
-  List<String> get pathSegments {
-    int start = _pathStart;
-    int end = _queryStart;
-    if (_uri.startsWith("/", start)) start++;
-    if (start == end) return const <String>[];
-    List<String> parts = [];
-    for (int i = start; i < end; i++) {
-      var char = _uri.codeUnitAt(i);
-      if (char == _SLASH) {
-        parts.add(_uri.substring(start, i));
-        start = i + 1;
-      }
-    }
-    parts.add(_uri.substring(start, end));
-    return new List<String>.unmodifiable(parts);
-  }
-
-  Map<String, String> get queryParameters {
-    if (!hasQuery) return const <String, String>{};
-    return new UnmodifiableMapView<String, String>(
-        Uri.splitQueryString(query));
-  }
-
-  Map<String, List<String>> get queryParametersAll {
-    if (!hasQuery) return const <String, List<String>>{};
-    Map queryParameterLists = _Uri._splitQueryStringAll(query);
-    for (var key in queryParameterLists.keys) {
-      queryParameterLists[key] =
-          new List<String>.unmodifiable(queryParameterLists[key]);
-    }
-    return new Map<String, List<String>>.unmodifiable(queryParameterLists);
-  }
-
-  bool _isPort(String port) {
-    int portDigitStart = _portStart + 1;
-    return portDigitStart + port.length == _pathStart &&
-           _uri.startsWith(port, portDigitStart);
-  }
-
-  Uri normalizePath() => this;
-
-  Uri removeFragment() {
-    if (!hasFragment) return this;
-    return new _SimpleUri(
-      _uri.substring(0, _fragmentStart),
-      _schemeEnd, _hostStart, _portStart,
-      _pathStart, _queryStart, _fragmentStart, _schemeCache);
-  }
-
-  Uri replace({String scheme,
-               String userInfo,
-               String host,
-               int port,
-               String path,
-               Iterable<String> pathSegments,
-               String query,
-               Map<String, dynamic/*String|Iterable<String>*/> queryParameters,
-               String fragment}) {
-    bool schemeChanged = false;
-    if (scheme != null) {
-      scheme = _Uri._makeScheme(scheme, 0, scheme.length);
-      schemeChanged = !_isScheme(scheme);
-    } else {
-      scheme = this.scheme;
-    }
-    bool isFile = (scheme == "file");
-    if (userInfo != null) {
-      userInfo = _Uri._makeUserInfo(userInfo, 0, userInfo.length);
-    } else if (_hostStart > 0) {
-      userInfo = _uri.substring(_schemeEnd + 3, _hostStart);
-    } else {
-      userInfo = "";
-    }
-    if (port != null) {
-      port = _Uri._makePort(port, scheme);
-    } else {
-      port = this.hasPort ? this.port : null;
-      if (schemeChanged) {
-        // The default port might have changed.
-        port = _Uri._makePort(port, scheme);
-      }
-    }
-    if (host != null) {
-      host = _Uri._makeHost(host, 0, host.length, false);
-    } else if (_hostStart > 0) {
-      host = _uri.substring(_hostStart, _portStart);
-    } else if (userInfo.isNotEmpty || port != null || isFile) {
-      host = "";
-    }
-
-    bool hasAuthority = host != null;
-    if (path != null || pathSegments != null) {
-      path = _Uri._makePath(path, 0, _stringOrNullLength(path), pathSegments,
-                           scheme, hasAuthority);
-    } else {
-      path = _uri.substring(_pathStart, _queryStart);
-      if ((isFile || (hasAuthority && !path.isEmpty)) &&
-          !path.startsWith('/')) {
-        path = "/" + path;
-      }
-    }
-
-    if (query != null || queryParameters != null) {
-      query = _Uri._makeQuery(
-          query, 0, _stringOrNullLength(query), queryParameters);
-    } else if (_queryStart < _fragmentStart) {
-      query = _uri.substring(_queryStart, _fragmentStart);
-    }
-
-    if (fragment != null) {
-      fragment = _Uri._makeFragment(fragment, 0, fragment.length);
-    } else if (_fragmentStart < _uri.length) {
-      fragment = _uri.substring(_fragmentStart + 1);
-    }
-
-    return new _Uri._internal(
-        scheme, userInfo, host, port, path, query, fragment);
-  }
-
-  Uri resolve(String reference) {
-    return resolveUri(Uri.parse(reference));
-  }
-
-  Uri resolveUri(Uri reference) {
-    if (reference is _SimpleUri) {
-      return _simpleMerge(this, reference);
-    }
-    return _toNonSimple().resolveUri(reference);
-  }
-
-  // Merge two simple URIs. This should always result in a prefix of
-  // one concatentated with a suffix of the other, possibly with a `/` in
-  // the middle of two merged paths, which is again simple.
-  // In a few cases, there might be a need for extra normalization, when
-  // resolving on top of a known scheme.
-  Uri _simpleMerge(_SimpleUri base, _SimpleUri ref) {
-    if (ref.hasScheme) return ref;
-    if (ref.hasAuthority) {
-      if (!base.hasScheme) return ref;
-      bool isSimple = true;
-      if (base._isFile) {
-        isSimple = !ref.hasEmptyPath;
-      } else if (base._isHttp) {
-        isSimple = !ref._isPort("80");
-      } else if (base._isHttps) {
-        isSimple = !ref._isPort("443");
-      }
-      if (isSimple) {
-        var delta = base._schemeEnd + 1;
-        var newUri = base._uri.substring(0, base._schemeEnd + 1) +
-                     ref._uri.substring(ref._schemeEnd + 1);
-        return new _SimpleUri(newUri,
-           base._schemeEnd,
-           ref._hostStart + delta,
-           ref._portStart + delta,
-           ref._pathStart + delta,
-           ref._queryStart + delta,
-           ref._fragmentStart + delta,
-           base._schemeCache);
-      } else {
-        // This will require normalization, so use the _Uri implementation.
-        return _toNonSimple().resolveUri(ref);
-      }
-    }
-    if (ref.hasEmptyPath) {
-      if (ref.hasQuery) {
-        int delta = base._queryStart - ref._queryStart;
-        var newUri = base._uri.substring(0, base._queryStart) +
-                     ref._uri.substring(ref._queryStart);
-        return new _SimpleUri(newUri,
-           base._schemeEnd,
-           base._hostStart,
-           base._portStart,
-           base._pathStart,
-           ref._queryStart + delta,
-           ref._fragmentStart + delta,
-           base._schemeCache);
-      }
-      if (ref.hasFragment) {
-        int delta = base._fragmentStart - ref._fragmentStart;
-        var newUri = base._uri.substring(0, base._fragmentStart) +
-                     ref._uri.substring(ref._fragmentStart);
-        return new _SimpleUri(newUri,
-           base._schemeEnd,
-           base._hostStart,
-           base._portStart,
-           base._pathStart,
-           base._queryStart,
-           ref._fragmentStart + delta,
-           base._schemeCache);
-      }
-      return base.removeFragment();
-    }
-    if (ref.hasAbsolutePath) {
-      var delta = base._pathStart - ref._pathStart;
-      var newUri = base._uri.substring(0, base._pathStart) +
-                   ref._uri.substring(ref._pathStart);
-      return new _SimpleUri(newUri,
-        base._schemeEnd,
-        base._hostStart,
-        base._portStart,
-        base._pathStart,
-        ref._queryStart + delta,
-        ref._fragmentStart + delta,
-        base._schemeCache);
-    }
-    if (base.hasEmptyPath && base.hasAuthority) {
-      // ref has relative non-empty path.
-      // Add a "/" in front, then leading "/../" segments are folded to "/".
-      int refStart = ref._pathStart;
-      while (ref._uri.startsWith("../", refStart)) {
-        refStart += 3;
-      }
-      var delta = base._pathStart - refStart + 1;
-      var newUri = "${base._uri.substring(0, base._pathStart)}/"
-                   "${ref._uri.substring(refStart)}";
-      return new _SimpleUri(newUri,
-        base._schemeEnd,
-        base._hostStart,
-        base._portStart,
-        base._pathStart,
-        ref._queryStart + delta,
-        ref._fragmentStart + delta,
-        base._schemeCache);
-    }
-    // Merge paths.
-    if (base._uri.startsWith("../", base._pathStart)) {
-      // Complex rare case, go slow.
-      return _toNonSimple().resolveUri(ref);
-    }
-
-    // The RFC 3986 algorithm merges the base path without its final segment
-    // (anything after the final "/", or everything if the base path doesn't
-    // contain any "/"), and the reference path.
-    // Then it removes "." and ".." segments using the remove-dot-segment
-    // algorithm.
-    // This code combines the two steps. It is simplified by knowing that
-    // the base path contains no "." or ".." segments, and the reference
-    // path can only contain leading ".." segments.
-
-    String baseUri = base._uri;
-    String refUri = ref._uri;
-    int baseStart = base._pathStart;
-    int baseEnd = base._queryStart;
-    int refStart = ref._pathStart;
-    int refEnd = ref._queryStart;
-    int backCount = 1;
-
-    int slashCount = 0;
-
-    // Count leading ".." segments in reference path.
-    while (refStart + 3 <= refEnd && refUri.startsWith("../", refStart)) {
-      refStart += 3;
-      backCount += 1;
-    }
-
-    // Extra slash inserted between base and reference path parts if
-    // the base path contains any slashes.
-    // (We could use a slash from the base path in most cases, but not if
-    // we remove the entire base path).
-    String insert = "";
-    while (baseEnd > baseStart) {
-      baseEnd--;
-      int char = baseUri.codeUnitAt(baseEnd);
-      if (char == _SLASH) {
-        insert = "/";
-        backCount--;
-        if (backCount == 0) break;
-      }
-    }
-    // If the base URI has no scheme or authority (`_pathStart == 0`)
-    // and a relative path, and we reached the beginning of the path,
-    // we have a special case.
-    if (baseEnd == 0 && !base.hasAbsolutePath) {
-      // Non-RFC 3986 behavior when resolving a purely relative path on top of
-      // another relative path: Don't make the result absolute.
-      insert = "";
-    }
-
-    var delta = baseEnd - refStart + insert.length;
-    var newUri = "${base._uri.substring(0, baseEnd)}$insert"
-               "${ref._uri.substring(refStart)}";
-
-    return new _SimpleUri(newUri,
-      base._schemeEnd,
-      base._hostStart,
-      base._portStart,
-      base._pathStart,
-      ref._queryStart + delta,
-      ref._fragmentStart + delta,
-      base._schemeCache);
-  }
-
-  String toFilePath({bool windows}) {
-    if (_schemeEnd >= 0 && !_isFile) {
-      throw new UnsupportedError(
-          "Cannot extract a file path from a $scheme URI");
-    }
-    if (_queryStart < _uri.length) {
-      if (_queryStart < _fragmentStart) {
-        throw new UnsupportedError(
-            "Cannot extract a file path from a URI with a query component");
-      }
-      throw new UnsupportedError(
-          "Cannot extract a file path from a URI with a fragment component");
-    }
-    if (windows == null) windows = _Uri._isWindows;
-    return windows ? _Uri._toWindowsFilePath(this) : _toFilePath();
-  }
-
-  String _toFilePath() {
-    if (_hostStart < _portStart) {
-      // Has authority and non-empty host.
-      throw new UnsupportedError(
-        "Cannot extract a non-Windows file path from a file URI "
-        "with an authority");
-    }
-    return this.path;
-  }
-
-  UriData get data {
-    assert(scheme != "data");
-    return null;
-  }
-
-  int get hashCode => _hashCodeCache ??= _uri.hashCode;
-
-  bool operator==(Object other) {
-    if (identical(this, other)) return true;
-    if (other is Uri) return _uri == other.toString();
-    return false;
-  }
-
-  Uri _toNonSimple() {
-    return new _Uri._internal(
-      this.scheme,
-      this.userInfo,
-      this.hasAuthority ? this.host: null,
-      this.hasPort ? this.port : null,
-      this.path,
-      this.hasQuery ? this.query : null,
-      this.hasFragment ? this.fragment : null
-    );
-  }
-
-  String toString() => _uri;
-}
-
-/// Checks whether [text] starts with "data:" at position [start].
-///
-/// The text must be long enough to allow reading five characters
-/// from the [start] position.
-///
-/// Returns an integer value which is zero if text starts with all-lowercase
-/// "data:" and 0x20 if the text starts with "data:" that isn't all lower-case.
-/// All other values means the text starts with some other character.
-int _startsWithData(String text, int start) {
-  // Multiply by 3 to avoid a non-colon character making delta be 0x20.
-  int delta = (text.codeUnitAt(start + 4) ^ _COLON) * 3;
-  delta |= text.codeUnitAt(start)     ^ 0x64 /*d*/;
-  delta |= text.codeUnitAt(start + 1) ^ 0x61 /*a*/;
-  delta |= text.codeUnitAt(start + 2) ^ 0x74 /*t*/;
-  delta |= text.codeUnitAt(start + 3) ^ 0x61 /*a*/;
-  return delta;
-}
-
-/// Helper function returning the length of a string, or `0` for `null`.
-int _stringOrNullLength(String s) => (s == null) ? 0 : s.length;
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 0bc3749..b4f835b 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -22889,7 +22889,7 @@
 
   @DomName('MediaStream.getAudioTracks')
   @DocsEditable()
-  @Creates('JSExtendableArray')
+  @Creates('JSExtendableArray|MediaStreamTrack')
   @Returns('JSExtendableArray')
   List<MediaStreamTrack> getAudioTracks() native;
 
@@ -22904,7 +22904,7 @@
 
   @DomName('MediaStream.getVideoTracks')
   @DocsEditable()
-  @Creates('JSExtendableArray')
+  @Creates('JSExtendableArray|MediaStreamTrack')
   @Returns('JSExtendableArray')
   List<MediaStreamTrack> getVideoTracks() native;
 
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index bc92d6d..68ec664 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -37662,10 +37662,10 @@
     if ((blob_OR_source_OR_stream is Blob || blob_OR_source_OR_stream == null)) {
       return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is MediaStream)) {
+    if ((blob_OR_source_OR_stream is MediaSource)) {
       return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is MediaSource)) {
+    if ((blob_OR_source_OR_stream is MediaStream)) {
       return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index 2c1684e..e365f3b 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -179,7 +179,7 @@
 
 Future compileSources(Map<String, String> sources,
                check(MockCompiler compiler)) {
-  Uri base = new Uri(scheme: 'source', path: '/');
+  Uri base = new Uri(scheme: 'source');
   Uri mainUri = base.resolve('main.dart');
   String mainCode = sources['main.dart'];
   Expect.isNotNull(mainCode, 'No source code found for "main.dart"');
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index 4b9c31a..fc08b6b 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -69,7 +69,7 @@
     // 2. Some code was refactored, and there are more methods.
     // Either situation could be problematic, but in situation 2, it is often
     // acceptable to increase [expectedMethodCount] a little.
-    int expectedMethodCount = 466;
+    int expectedMethodCount = 432;
     Expect.isTrue(
         generatedCode.length <= expectedMethodCount,
         'Too many compiled methods: '
diff --git a/tests/corelib/data_uri_test.dart b/tests/corelib/data_uri_test.dart
index 41f2290..1a21be1 100644
--- a/tests/corelib/data_uri_test.dart
+++ b/tests/corelib/data_uri_test.dart
@@ -18,13 +18,6 @@
   testRoundTrip("blåbærgrød", UTF8);
   testRoundTrip("blåbærgrød", LATIN1);
 
-  testUriEquals("data:,abc?d#e");
-  testUriEquals("DATA:,ABC?D#E");
-  testUriEquals("data:,a%20bc?d#e");
-  testUriEquals("DATA:,A%20BC?D#E");
-  testUriEquals("data:,a%62c?d#e");
-  testUriEquals("DATA:,A%42C?D#E");
-
   testUtf8Encoding("\u1000\uffff");
   testBytes();
   testInvalidCharacters();
@@ -257,11 +250,3 @@
   Expect.equals(expect.hasFragment, actual.hasFragment, "hasFragment");
   Expect.equals(expect.fragment, actual.fragment, "fragment");
 }
-
-void testUriEquals(String uriText) {
-  var data = UriData.parse(uriText);
-  var uri = Uri.parse(uriText);
-  Expect.equals(data.uri, uri);
-  Expect.equals(data.toString(), uri.data.toString());
-  Expect.equals(data.toString(), uri.toString());
-}
diff --git a/tests/corelib/uri_test.dart b/tests/corelib/uri_test.dart
index 3d24e2d..ef7a9a3 100644
--- a/tests/corelib/uri_test.dart
+++ b/tests/corelib/uri_test.dart
@@ -10,12 +10,6 @@
 testUri(String uriText, bool isAbsolute) {
   var uri = Uri.parse(uriText);
 
-  // Test that parsing a substring works the same as parsing the string.
-  String wrapper = "://@[]:/%?#";
-  var embeddedUri = Uri.parse(
-       "$wrapper$uri$wrapper", wrapper.length, uriText.length + wrapper.length);
-
-  Expect.equals(uri, embeddedUri);
   Expect.equals(isAbsolute, uri.isAbsolute);
   Expect.stringEquals(uriText, uri.toString());
 
@@ -88,8 +82,7 @@
   final urisSample = "http://a/b/c/d;p?q";
   Uri base = Uri.parse(urisSample);
   testResolve(expect, relative) {
-    String name = "$base << $relative";
-    Expect.stringEquals(expect, base.resolve(relative).toString(), name);
+    Expect.stringEquals(expect, base.resolve(relative).toString());
   }
 
   // From RFC 3986.
@@ -139,232 +132,19 @@
   // Additional tests (not from RFC 3986).
   testResolve("http://a/b/g;p/h;s",    "../g;p/h;s");
 
-  base = Uri.parse("s:a/b");
-  testResolve("s:a/c", "c");
-  testResolve("s:/c", "../c");
-
-  base = Uri.parse("S:a/b");
-  testResolve("s:a/c", "c");
-  testResolve("s:/c", "../c");
-
-  base = Uri.parse("s:foo");
-  testResolve("s:bar", "bar");
-  testResolve("s:bar", "../bar");
-
-  base = Uri.parse("S:foo");
-  testResolve("s:bar", "bar");
-  testResolve("s:bar", "../bar");
-
-  // Special-case (deliberate non-RFC behavior).
-  base = Uri.parse("foo/bar");
-  testResolve("foo/baz", "baz");
-  testResolve("baz", "../baz");
-
-  base = Uri.parse("s:/foo");
-  testResolve("s:/bar", "bar");
-  testResolve("s:/bar", "../bar");
-
-  base = Uri.parse("S:/foo");
-  testResolve("s:/bar", "bar");
-  testResolve("s:/bar", "../bar");
-
   // Test non-URI base (no scheme, no authority, relative path).
   base = Uri.parse("a/b/c?_#_");
   testResolve("a/b/g?q#f", "g?q#f");
   testResolve("./", "../..");
   testResolve("../", "../../..");
   testResolve("a/b/", ".");
-  testResolve("c", "../../c");  // Deliberate non-RFC behavior.
+  testResolve("c", "../../c");
   base = Uri.parse("../../a/b/c?_#_");  // Initial ".." in base url.
   testResolve("../../a/d", "../d");
   testResolve("../../../d", "../../../d");
 
-  base = Uri.parse("s://h/p?q#f");  // A simple base.
-  // Simple references:
-  testResolve("s2://h2/P?Q#F", "s2://h2/P?Q#F");
-  testResolve("s://h2/P?Q#F", "//h2/P?Q#F");
-  testResolve("s://h/P?Q#F", "/P?Q#F");
-  testResolve("s://h/p?Q#F", "?Q#F");
-  testResolve("s://h/p?q#F", "#F");
-  testResolve("s://h/p?q", "");
-  // Non-simple references:
-  testResolve("s2://I@h2/P?Q#F%20", "s2://I@h2/P?Q#F%20");
-  testResolve("s://I@h2/P?Q#F%20", "//I@h2/P?Q#F%20");
-  testResolve("s://h2/P?Q#F%20", "//h2/P?Q#F%20");
-  testResolve("s://h/P?Q#F%20", "/P?Q#F%20");
-  testResolve("s://h/p?Q#F%20", "?Q#F%20");
-  testResolve("s://h/p?q#F%20", "#F%20");
-
-  base = Uri.parse("s://h/p1/p2/p3");  // A simple base with a path.
-  testResolve("s://h/p1/p2/", ".");
-  testResolve("s://h/p1/p2/", "./");
-  testResolve("s://h/p1/", "..");
-  testResolve("s://h/p1/", "../");
-  testResolve("s://h/", "../..");
-  testResolve("s://h/", "../../");
-  testResolve("s://h/p1/%20", "../%20");
-  testResolve("s://h/", "../../../..");
-  testResolve("s://h/", "../../../../");
-
-  base = Uri.parse("s://h/p?q#f%20");  // A non-simpe base.
-  // Simple references:
-  testResolve("s2://h2/P?Q#F", "s2://h2/P?Q#F");
-  testResolve("s://h2/P?Q#F", "//h2/P?Q#F");
-  testResolve("s://h/P?Q#F", "/P?Q#F");
-  testResolve("s://h/p?Q#F", "?Q#F");
-  testResolve("s://h/p?q#F", "#F");
-  testResolve("s://h/p?q", "");
-  // Non-simple references:
-  testResolve("s2://I@h2/P?Q#F%20", "s2://I@h2/P?Q#F%20");
-  testResolve("s://I@h2/P?Q#F%20", "//I@h2/P?Q#F%20");
-  testResolve("s://h2/P?Q#F%20", "//h2/P?Q#F%20");
-  testResolve("s://h/P?Q#F%20", "/P?Q#F%20");
-  testResolve("s://h/p?Q#F%20", "?Q#F%20");
-  testResolve("s://h/p?q#F%20", "#F%20");
-
-  base = Uri.parse("S://h/p1/p2/p3");  // A non-simple base with a path.
-  testResolve("s://h/p1/p2/", ".");
-  testResolve("s://h/p1/p2/", "./");
-  testResolve("s://h/p1/", "..");
-  testResolve("s://h/p1/", "../");
-  testResolve("s://h/", "../..");
-  testResolve("s://h/", "../../");
-  testResolve("s://h/p1/%20", "../%20");
-  testResolve("s://h/", "../../../..");
-  testResolve("s://h/", "../../../../");
-
-  base = Uri.parse("../../../");  // A simple relative path.
-  testResolve("../../../a", "a");
-  testResolve("../../../../a", "../a");
-  testResolve("../../../a%20", "a%20");
-  testResolve("../../../../a%20", "../a%20");
-
-  // Tests covering the branches of the merge algorithm in RFC 3986
-  // with both simple and complex base URIs.
-  for (var b in ["s://a/pa/pb?q#f", "s://a/pa/pb?q#f%20"]) {
-    var origBase = Uri.parse(b);
-    base = origBase;
-
-    // if defined(R.scheme) then ...
-    testResolve("s2://a2/p2?q2#f2", "s2://a2/p2?q2#f2");
-    // else, if defined(R.authority) then ...
-    testResolve("s://a2/p2?q2#f2", "//a2/p2?q2#f2");
-    testResolve("s://a2/?q2#f2", "//a2/../?q2#f2");
-    testResolve("s://a2?q2#f2", "//a2?q2#f2");
-    testResolve("s://a2#f2", "//a2#f2");
-    testResolve("s://a2", "//a2");
-    // else, if (R.path == "") then ...
-    //   if defined(R.query) then
-    testResolve("s://a/pa/pb?q2#f2", "?q2#f2");
-    testResolve("s://a/pa/pb?q2", "?q2");
-    //   else
-    testResolve("s://a/pa/pb?q#f2", "#f2");
-    testResolve("s://a/pa/pb?q", "");
-    // else, if (R.path starts-with "/") then ...
-    testResolve("s://a/p2?q2#f2", "/p2?q2#f2");
-    testResolve("s://a/?q2#f2", "/?q2#f2");
-    testResolve("s://a/#f2", "/#f2");
-    testResolve("s://a/", "/");
-    testResolve("s://a/", "/../");
-    // else ... T.path = merge(Base.path, R.path)
-    // ... remove-dot-fragments(T.path) ...
-    // (Cover the merge function and the remove-dot-fragments functions too).
-
-    // If base has authority and empty path ...
-    var emptyPathBase = Uri.parse(b.replaceFirst("/pa/pb", ""));
-    base = emptyPathBase;
-    testResolve("s://a/p2?q2#f2", "p2?q2#f2");
-    testResolve("s://a/p2#f2", "p2#f2");
-    testResolve("s://a/p2", "p2");
-
-    base = origBase;
-    // otherwise
-    // (Cover both no authority and non-empty path and both).
-    var noAuthEmptyPathBase = Uri.parse(b.replaceFirst("//a/pa/pb", ""));
-    var noAuthAbsPathBase = Uri.parse(b.replaceFirst("//a", ""));
-    var noAuthRelPathBase = Uri.parse(b.replaceFirst("//a/", ""));
-    var noAuthRelSinglePathBase = Uri.parse(b.replaceFirst("//a/pa/", ""));
-
-    testResolve("s://a/pa/p2?q2#f2", "p2?q2#f2");
-    testResolve("s://a/pa/p2#f2", "p2#f2");
-    testResolve("s://a/pa/p2", "p2");
-
-    base = noAuthEmptyPathBase;
-    testResolve("s:p2?q2#f2", "p2?q2#f2");
-    testResolve("s:p2#f2", "p2#f2");
-    testResolve("s:p2", "p2");
-
-    base = noAuthAbsPathBase;
-    testResolve("s:/pa/p2?q2#f2", "p2?q2#f2");
-    testResolve("s:/pa/p2#f2", "p2#f2");
-    testResolve("s:/pa/p2", "p2");
-
-    base = noAuthRelPathBase;
-    testResolve("s:pa/p2?q2#f2", "p2?q2#f2");
-    testResolve("s:pa/p2#f2", "p2#f2");
-    testResolve("s:pa/p2", "p2");
-
-    base = noAuthRelSinglePathBase;
-    testResolve("s:p2?q2#f2", "p2?q2#f2");
-    testResolve("s:p2#f2", "p2#f2");
-    testResolve("s:p2", "p2");
-
-    // Then remove dot segments.
-
-    // A. if input buffer starts with "../" or "./".
-    // This only happens if base has only a single (may be empty) segment and
-    // no slash.
-    base = emptyPathBase;
-    testResolve("s://a/p2", "../p2");
-    testResolve("s://a/", "../");
-    testResolve("s://a/", "..");
-    testResolve("s://a/p2", "./p2");
-    testResolve("s://a/", "./");
-    testResolve("s://a/", ".");
-    testResolve("s://a/p2", "../../p2");
-    testResolve("s://a/p2", "../../././p2");
-
-    base = noAuthRelSinglePathBase;
-    testResolve("s:p2", "../p2");
-    testResolve("s:", "../");
-    testResolve("s:", "..");
-    testResolve("s:p2", "./p2");
-    testResolve("s:", "./");
-    testResolve("s:", ".");
-    testResolve("s:p2", "../../p2");
-    testResolve("s:p2", "../../././p2");
-
-    // B. if input buffer starts with "/./" or is "/.". replace with "/".
-    // (The URI implementation removes the "." path segments when parsing,
-    // so this case isn't handled by merge).
-    base = origBase;
-    testResolve("s://a/pa/p2", "./p2");
-
-    // C. if input buffer starts with "/../" or is "/..", replace with "/"
-    // and remove preceeding segment.
-    testResolve("s://a/p2", "../p2");
-    var longPathBase = Uri.parse(b.replaceFirst("/pb", "/pb/pc/pd"));
-    base = longPathBase;
-    testResolve("s://a/pa/pb/p2", "../p2");
-    testResolve("s://a/pa/p2", "../../p2");
-    testResolve("s://a/p2", "../../../p2");
-    testResolve("s://a/p2", "../../../../p2");
-    var noAuthRelLongPathBase =
-        Uri.parse(b.replaceFirst("//a/pa/pb", "pa/pb/pc/pd"));
-    base = noAuthRelLongPathBase;
-    testResolve("s:pa/pb/p2", "../p2");
-    testResolve("s:pa/p2", "../../p2");
-    testResolve("s:/p2", "../../../p2");
-    testResolve("s:/p2", "../../../../p2");
-
-    // D. if the input buffer contains only ".." or ".", remove it.
-    base = noAuthEmptyPathBase;
-    testResolve("s:", "..");
-    testResolve("s:", ".");
-    base = noAuthRelSinglePathBase;
-    testResolve("s:", "..");
-    testResolve("s:", ".");
-  }
+  base = Uri.parse("s:a/b");
+  testResolve("s:/c", "../c");
 }
 
 void testResolvePath(String expected, String path) {
@@ -718,11 +498,6 @@
                           query: null,
                           fragment: null).toString());
   Expect.stringEquals("file:///", Uri.parse("file:").toString());
-  Expect.stringEquals("file:///", Uri.parse("file:/").toString());
-  Expect.stringEquals("file:///", Uri.parse("file:").toString());
-  Expect.stringEquals("file:///foo", Uri.parse("file:foo").toString());
-  Expect.stringEquals("file:///foo", Uri.parse("file:/foo").toString());
-  Expect.stringEquals("file://foo/", Uri.parse("file://foo").toString());
 
   testResolvePath("/a/g", "/a/b/c/./../../g");
   testResolvePath("/a/g", "/a/b/c/./../../g");
diff --git a/tools/VERSION b/tools/VERSION
index 261629f..bc466cc 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 18
 PATCH 0
 PRERELEASE 4
-PRERELEASE_PATCH 3
+PRERELEASE_PATCH 4
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index 37877f1..2b2d594 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -255,12 +255,12 @@
     ],
 
     'MediaStream.getAudioTracks': [
-      "@Creates('JSExtendableArray')",
+      "@Creates('JSExtendableArray|MediaStreamTrack')",
       "@Returns('JSExtendableArray')",
     ],
 
     'MediaStream.getVideoTracks': [
-      "@Creates('JSExtendableArray')",
+      "@Creates('JSExtendableArray|MediaStreamTrack')",
       "@Returns('JSExtendableArray')",
     ],
 
